├── .babelrc
├── .distignore
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .github
└── workflows
│ ├── codeql-analysis.yml
│ ├── deploy-to-wpdotorg.yml
│ └── update-wpdotorg-assets.yml
├── .gitignore
├── .nvmrc
├── .travis.yml
├── .wordpress-org
├── banner-1544x500.png
├── banner-772x250.png
├── icon-128x128.png
├── icon-256x256.png
├── icon.svg
├── screenshot-1.png
├── screenshot-2.png
├── screenshot-4.png
├── screenshot-5.png
└── screenshot-6.png
├── README.md
├── analogwp-templates.php
├── assets
├── css
│ ├── admin-settings.css
│ ├── elementor-modal.css
│ ├── onboarding-screen.css
│ └── sk-components.css
├── img
│ ├── analog.svg
│ ├── blocks.svg
│ ├── elementor.svg
│ ├── gopro_frames.png
│ ├── placeholder.svg
│ └── triangle.svg
└── js
│ ├── admin-settings.js
│ ├── admin.js
│ ├── elementor-modal.js
│ ├── kit-list.js
│ ├── onboarding-screen.js
│ └── quick-edit.js
├── client
├── AnalogContext.js
├── App.js
├── Header.js
├── Modal.js
├── Nav.js
├── Notifications.js
├── ProModal.js
├── Synchronization.js
├── Template.js
├── Templates.js
├── api.js
├── blocks
│ ├── BlockList.js
│ ├── Sidebar.js
│ └── blocks.js
├── collection
│ └── Collection.js
├── contexts
│ └── ThemeContext.js
├── filters.js
├── helpers
│ ├── Empty.js
│ └── Image.js
├── icons
│ ├── analogpro.js
│ ├── close.js
│ ├── error.js
│ ├── loader.js
│ ├── logo.js
│ ├── notice.js
│ ├── refresh.js
│ ├── star.js
│ └── success.js
├── index.js
├── modal
│ └── Preview.js
├── popup.js
├── popups
│ └── ImportTemplate.js
├── stylekits
│ └── stylekits.js
└── utils.js
├── codeception.dist.yml
├── composer.json
├── composer.lock
├── freemius
├── LICENSE.txt
├── README.md
├── assets
│ ├── css
│ │ ├── admin
│ │ │ ├── account.css
│ │ │ ├── add-ons.css
│ │ │ ├── affiliation.css
│ │ │ ├── checkout.css
│ │ │ ├── clone-resolution.css
│ │ │ ├── common.css
│ │ │ ├── connect.css
│ │ │ ├── debug.css
│ │ │ ├── dialog-boxes.css
│ │ │ ├── gdpr-optin-notice.css
│ │ │ ├── index.php
│ │ │ ├── optout.css
│ │ │ └── plugins.css
│ │ ├── customizer.css
│ │ └── index.php
│ ├── img
│ │ ├── analogwp-templates.png
│ │ ├── index.php
│ │ ├── plugin-icon.png
│ │ ├── style-kits-pr.png
│ │ ├── style-kits-pro.png
│ │ └── theme-icon.png
│ ├── index.php
│ └── js
│ │ ├── index.php
│ │ ├── jquery.form.js
│ │ ├── nojquery.ba-postmessage.js
│ │ ├── postmessage.js
│ │ └── pricing
│ │ ├── 14fb1bd5b7c41648488b06147f50a0dc.svg
│ │ ├── 178afa6030e76635dbe835e111d2c507.png
│ │ ├── 27b5a722a5553d9de0170325267fccec.png
│ │ ├── 4375c4a3ddc6f637c2ab9a2d7220f91e.png
│ │ ├── 4529cac82a2d1f300d3c4702b7b5e8f3.svg
│ │ ├── 5480ed23b199531a8cbc05924f26952b.png
│ │ ├── b4f3b958f4a019862d81b15f3f8eee3a.svg
│ │ ├── c03f665db27af43971565560adfba594.png
│ │ ├── cb5fc4f6ec7ada72e986f6e7dde365bf.png
│ │ ├── dd89563360f0272635c8f0ab7d7f1402.png
│ │ ├── e366d70661d8ad2493bd6afbd779f125.png
│ │ ├── f18006f6535a1a6e9c6bfbffafe6f18a.svg
│ │ ├── f3aac72a8e63997d6bb888f816457e9b.png
│ │ ├── f928f1be99776af83e8e6be4baf8ffe7.svg
│ │ ├── fde48e4609a6ddc11d639fc2421f2afd.png
│ │ ├── freemius-pricing.js
│ │ └── freemius-pricing.js.LICENSE.txt
├── config.php
├── includes
│ ├── class-freemius-abstract.php
│ ├── class-freemius.php
│ ├── class-fs-admin-notices.php
│ ├── class-fs-api.php
│ ├── class-fs-garbage-collector.php
│ ├── class-fs-lock.php
│ ├── class-fs-logger.php
│ ├── class-fs-options.php
│ ├── class-fs-plugin-updater.php
│ ├── class-fs-security.php
│ ├── class-fs-storage.php
│ ├── class-fs-user-lock.php
│ ├── customizer
│ │ ├── class-fs-customizer-support-section.php
│ │ ├── class-fs-customizer-upsell-control.php
│ │ └── index.php
│ ├── debug
│ │ ├── class-fs-debug-bar-panel.php
│ │ ├── debug-bar-start.php
│ │ └── index.php
│ ├── entities
│ │ ├── class-fs-affiliate-terms.php
│ │ ├── class-fs-affiliate.php
│ │ ├── class-fs-billing.php
│ │ ├── class-fs-entity.php
│ │ ├── class-fs-payment.php
│ │ ├── class-fs-plugin-info.php
│ │ ├── class-fs-plugin-license.php
│ │ ├── class-fs-plugin-plan.php
│ │ ├── class-fs-plugin-tag.php
│ │ ├── class-fs-plugin.php
│ │ ├── class-fs-pricing.php
│ │ ├── class-fs-scope-entity.php
│ │ ├── class-fs-site.php
│ │ ├── class-fs-subscription.php
│ │ ├── class-fs-user.php
│ │ └── index.php
│ ├── fs-core-functions.php
│ ├── fs-essential-functions.php
│ ├── fs-html-escaping-functions.php
│ ├── fs-plugin-info-dialog.php
│ ├── index.php
│ ├── l10n.php
│ ├── managers
│ │ ├── class-fs-admin-menu-manager.php
│ │ ├── class-fs-admin-notice-manager.php
│ │ ├── class-fs-cache-manager.php
│ │ ├── class-fs-checkout-manager.php
│ │ ├── class-fs-clone-manager.php
│ │ ├── class-fs-contact-form-manager.php
│ │ ├── class-fs-debug-manager.php
│ │ ├── class-fs-gdpr-manager.php
│ │ ├── class-fs-key-value-storage.php
│ │ ├── class-fs-license-manager.php
│ │ ├── class-fs-option-manager.php
│ │ ├── class-fs-permission-manager.php
│ │ ├── class-fs-plan-manager.php
│ │ ├── class-fs-plugin-manager.php
│ │ └── index.php
│ ├── sdk
│ │ ├── Exceptions
│ │ │ ├── ArgumentNotExistException.php
│ │ │ ├── EmptyArgumentException.php
│ │ │ ├── Exception.php
│ │ │ ├── InvalidArgumentException.php
│ │ │ ├── OAuthException.php
│ │ │ └── index.php
│ │ ├── FreemiusBase.php
│ │ ├── FreemiusWordPress.php
│ │ ├── LICENSE.txt
│ │ └── index.php
│ └── supplements
│ │ ├── fs-essential-functions-1.1.7.1.php
│ │ ├── fs-essential-functions-2.2.1.php
│ │ ├── fs-migration-2.5.1.php
│ │ └── index.php
├── index.php
├── languages
│ ├── freemius-cs_CZ.mo
│ ├── freemius-da_DK.mo
│ ├── freemius-de_DE.mo
│ ├── freemius-es_ES.mo
│ ├── freemius-fr_FR.mo
│ ├── freemius-he_IL.mo
│ ├── freemius-hu_HU.mo
│ ├── freemius-it_IT.mo
│ ├── freemius-ja.mo
│ ├── freemius-nl_NL.mo
│ ├── freemius-ru_RU.mo
│ ├── freemius-ta.mo
│ ├── freemius-zh_CN.mo
│ ├── freemius.pot
│ └── index.php
├── require.php
├── start.php
└── templates
│ ├── account.php
│ ├── account
│ ├── billing.php
│ ├── index.php
│ ├── partials
│ │ ├── activate-license-button.php
│ │ ├── addon.php
│ │ ├── deactivate-license-button.php
│ │ ├── disconnect-button.php
│ │ ├── index.php
│ │ └── site.php
│ └── payments.php
│ ├── add-ons.php
│ ├── add-trial-to-pricing.php
│ ├── admin-notice.php
│ ├── ajax-loader.php
│ ├── api-connectivity-message-js.php
│ ├── auto-installation.php
│ ├── checkout.php
│ ├── checkout
│ ├── frame.php
│ ├── process-redirect.php
│ └── redirect.php
│ ├── clone-resolution-js.php
│ ├── connect.php
│ ├── connect
│ ├── index.php
│ ├── permission.php
│ └── permissions-group.php
│ ├── contact.php
│ ├── debug.php
│ ├── debug
│ ├── api-calls.php
│ ├── index.php
│ ├── logger.php
│ ├── plugins-themes-sync.php
│ └── scheduled-crons.php
│ ├── email.php
│ ├── forms
│ ├── affiliation.php
│ ├── data-debug-mode.php
│ ├── deactivation
│ │ ├── contact.php
│ │ ├── form.php
│ │ ├── index.php
│ │ └── retry-skip.php
│ ├── email-address-update.php
│ ├── index.php
│ ├── license-activation.php
│ ├── optout.php
│ ├── premium-versions-upgrade-handler.php
│ ├── premium-versions-upgrade-metadata.php
│ ├── resend-key.php
│ ├── subscription-cancellation.php
│ ├── trial-start.php
│ └── user-change.php
│ ├── gdpr-optin-js.php
│ ├── index.php
│ ├── js
│ ├── index.php
│ ├── jquery.content-change.php
│ ├── open-license-activation.php
│ ├── permissions.php
│ └── style-premium-theme.php
│ ├── partials
│ ├── index.php
│ └── network-activation.php
│ ├── plugin-icon.php
│ ├── plugin-info
│ ├── description.php
│ ├── features.php
│ ├── index.php
│ └── screenshots.php
│ ├── pricing.php
│ ├── secure-https-header.php
│ ├── sticky-admin-notice-js.php
│ ├── tabs-capture-js.php
│ └── tabs.php
├── gulpfile.js
├── inc
├── Consumer.php
├── Core
│ ├── SVGs
│ │ └── Allow.php
│ ├── Storage
│ │ └── Transients.php
│ └── Util
│ │ └── Migration.php
├── Database_Upgrader.php
├── Plugin.php
├── Utils.php
├── admin
│ ├── Notice.php
│ ├── Notices.php
│ └── class-admin.php
├── api
│ ├── class-local.php
│ └── class-remote.php
├── class-admin-settings.php
├── class-analog-importer.php
├── class-base.php
├── class-beta-testers.php
├── class-cron.php
├── class-elementor.php
├── class-formatter.php
├── class-import-image.php
├── class-onboarding.php
├── class-options.php
├── class-quick-edit.php
├── class-tracker.php
├── cli
│ └── commands.php
├── elementor
│ ├── Google_Fonts.php
│ ├── Promotions.php
│ ├── Reset_Default_Style_Trait.php
│ ├── class-ang-action.php
│ ├── class-colors.php
│ ├── class-finder-shortcuts.php
│ ├── class-post-type.php
│ ├── class-tools.php
│ ├── class-typography.php
│ ├── css
│ │ └── hint.min.css
│ ├── globals
│ │ ├── class-colors.php
│ │ ├── class-controller.php
│ │ └── class-typography.php
│ ├── js
│ │ ├── ang-action.js
│ │ ├── ang-cpt-tools.js
│ │ ├── ang-typography.js
│ │ └── cssbeautify.min.js
│ ├── kit
│ │ ├── Instance_List_Table.php
│ │ ├── Kits_List_Table.php
│ │ ├── Manager.php
│ │ ├── kit-content.json
│ │ ├── tabs
│ │ │ └── Theme_Style_Kits.php
│ │ └── views
│ │ │ └── trash-kit-confirmation.php
│ ├── sections
│ │ └── background-color-classes.php
│ ├── tags
│ │ ├── class-dark-background.php
│ │ └── class-light-background.php
│ └── trait-document.php
├── register-settings.php
├── settings-helpers.php
├── settings
│ ├── class-settings-experiments.php
│ ├── class-settings-extensions.php
│ ├── class-settings-general.php
│ ├── class-settings-gopro.php
│ ├── class-settings-misc.php
│ ├── class-settings-page.php
│ ├── class-settings-version-control.php
│ └── views
│ │ ├── html-admin-settings-gopro.php
│ │ └── html-admin-settings.php
└── upgrade-functions.php
├── languages
├── ang-analogwp-app.json
└── ang.pot
├── package-lock.json
├── package.json
├── phpcs.xml.dist
├── readme.txt
├── scoper.inc.php
├── tests
├── _data
│ └── .gitkeep
├── _output
│ └── .gitignore
├── _support
│ ├── AcceptanceTester.php
│ ├── ApiTester.php
│ ├── FunctionalTester.php
│ ├── Helper
│ │ ├── Acceptance.php
│ │ ├── Api.php
│ │ ├── Functional.php
│ │ ├── Unit.php
│ │ └── Wpunit.php
│ ├── UnitTester.php
│ ├── WpunitTester.php
│ └── _generated
│ │ └── .gitignore
├── acceptance.suite.yml
├── acceptance
│ ├── SaveSettingsCest.php
│ └── StyleKitExportImportCest.php
├── api.suite.yml
├── api
│ └── CheckEndpointsCest.php
├── functional.suite.yml
├── unit.suite.yml
└── wpunit.suite.yml
├── third-party
├── composer.json
└── vendor
│ ├── autoload.php
│ ├── composer
│ ├── ClassLoader.php
│ ├── LICENSE
│ ├── autoload_classmap.php
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── autoload_real.php
│ └── autoload_static.php
│ ├── enshrined
│ └── svg-sanitize
│ │ ├── composer.json
│ │ └── src
│ │ ├── ElementReference
│ │ ├── Resolver.php
│ │ ├── Subject.php
│ │ └── Usage.php
│ │ ├── Exceptions
│ │ └── NestingException.php
│ │ ├── Helper.php
│ │ ├── Sanitizer.php
│ │ ├── data
│ │ ├── AllowedAttributes.php
│ │ ├── AllowedTags.php
│ │ ├── AttributeInterface.php
│ │ ├── TagInterface.php
│ │ └── XPath.php
│ │ └── svg-scanner.php
│ └── scoper-autoload.php
└── uninstall.php
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env",
4 | "@babel/preset-react"
5 | ],
6 | "plugins": [
7 | "@babel/plugin-proposal-class-properties"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.distignore:
--------------------------------------------------------------------------------
1 | # Directories
2 | /.wordpress-org
3 | /.git
4 | /.github
5 | /.babelrc
6 | /.eslintignore
7 | /.vscode
8 | /phpcs.xml
9 | /node_modules
10 | /tests
11 | /bin
12 | /phpunit.xml
13 | /build
14 | /client
15 | .nvmrc
16 | .wp-env.json
17 | phpcs.xml.dist
18 |
19 | # Exclude vendor folder, except required dependencies.
20 | /vendor
21 | !/vendor/composer
22 | !/vendor/autoload.php
23 |
24 | # Files
25 | .babelrc
26 | .distignore
27 | .eslintignore
28 | .eslintrc.json
29 | .gitignore
30 | .editorconfig
31 | .travisyml
32 | .codeception.dist.yml
33 | DOCKER_ENV
34 | docker_tag
35 | Dockerfile-php-build
36 | output.log
37 | CHANGELOG.md
38 | CODE_OF_CONDUCT.md
39 | CONTRIBUTING.md
40 | CREDITS.md
41 | LICENSE.md
42 | README.md
43 | composer.json
44 | composer.lock
45 | package-lock.json
46 | yarn.lock
47 | package.json
48 | phpcs.xml
49 | phpunit.xml
50 | webpack.config.js
51 | gulpfile.js
52 | gulp.config.json
53 | scoper.inc.php
54 |
55 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = tab
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [{package.json, *.yml}]
12 | indent_style = space
13 | indent_size = 2
14 |
15 | [composer.json, eslintrc.json]
16 | indent_style = space
17 | indent_size = 4
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/*.min.js
2 | **/*.build.js
3 | **/node_modules/**
4 | **/vendor/**
5 | build
6 | coverage
7 | cypress
8 | node_modules
9 | vendor
10 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-to-wpdotorg.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to WordPress.org
2 |
3 | on:
4 | push:
5 | tags:
6 | - "*"
7 |
8 | jobs:
9 | tag:
10 | name: New tag
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@master
14 |
15 | - name: Install Composer dependencies
16 | uses: php-actions/composer@v6
17 | with:
18 | version: 2
19 | php_version: '8.0'
20 |
21 | - name: Setup Node
22 | uses: actions/setup-node@v1
23 | with:
24 | node-version: '21'
25 |
26 | - name: Install dependencies
27 | run: npm install
28 |
29 | - name: Prepare release build
30 | run: npm run gh:release
31 |
32 | - name: WordPress Plugin Deploy
33 | uses: 10up/action-wordpress-plugin-deploy@master
34 | env:
35 | BUILD_DIR: ./build/analogwp-templates
36 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
37 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
38 |
--------------------------------------------------------------------------------
/.github/workflows/update-wpdotorg-assets.yml:
--------------------------------------------------------------------------------
1 | name: Plugin asset/readme update
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 |
8 | env:
9 | SLUG: analogwp-templates
10 |
11 | jobs:
12 | master:
13 | name: Push to trunk
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@master
17 | - name: WordPress.org plugin asset/readme update
18 | uses: 10up/action-wordpress-plugin-asset-update@stable
19 | env:
20 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
21 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
22 | IGNORE_OTHER_FILES: true
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /src/js/app/test.js
2 | /assets/js/app.js.map
3 | /build
4 | /assets/js/app.js
5 | /assets/js/app/
6 | node_modules/
7 | /assets/fonts/
8 | /assets/js/blocksLibrary.js
9 | /assets/js/blocksLibrary.js.map
10 |
11 |
12 | /.idea/**
13 | /.idea/workspace.xml
14 | /inc/elementor/js/ang-action.min.js
15 | /inc/elementor/js/ang-typography.min.js
16 | /inc/elementor/js/*.min.js
17 | /gulp.config.json
18 |
19 | /vendor/
20 | /.env
21 | /tests/_data/dump.sql
22 | tests/_output/*
23 | tests/_support/_generated/*
24 | tests/cache/*
25 | tests/error.log
26 | .DS_Store
27 |
28 | analogwp-templates.zip
29 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 21
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | dist: trusty
3 | sudo: false
4 |
5 | php:
6 | - "7.4"
7 | - "8.0"
8 | - "8.1"
9 |
10 | env:
11 | - WP_VERSION=latest WP_MULTISITE=0
12 | - WP_VERSION=6.6 WP_MULTISITE=0
13 |
14 | matrix:
15 | include:
16 | - php: "8.1"
17 | env: WP_VERSION=latest WP_MULTISITE=0
18 | - php: "8.0"
19 | env: WP_VERSION=latest WP_MULTISITE=0
20 | - php: "7.4"
21 | env: WP_VERSION=latest WP_MULTISITE=0
22 |
23 | branches:
24 | only:
25 | - develop
26 | - /^feature\/.*$/
27 |
28 | script:
29 | - php -v
30 | - phpunit --version
31 |
--------------------------------------------------------------------------------
/.wordpress-org/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/banner-1544x500.png
--------------------------------------------------------------------------------
/.wordpress-org/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/banner-772x250.png
--------------------------------------------------------------------------------
/.wordpress-org/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/icon-128x128.png
--------------------------------------------------------------------------------
/.wordpress-org/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/icon-256x256.png
--------------------------------------------------------------------------------
/.wordpress-org/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-1.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-2.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-4.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-5.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-6.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://wordpress.org/plugins/analogwp-templates/) [](https://wordpress.org/plugins/analogwp-templates/) [](https://github.com/analogwp/analogwp-templates/blob/master/license.txt) 
2 |
3 | 
4 | []()
5 | [](https://wordpress.org/plugins/analogwp-templates/)
6 |
7 | Analog Templates
8 | ===
9 |
10 | Your layouts deserve more. Use inspiring, extendable design resources for consistent websites and sharp workflow.
11 |
12 | More information can be found at [analogwp.com](https://analogwp.com/).
13 |
14 | ### Build Commands
15 | - `npm run dev-app` for development.
16 | - `npm run build` for production and release files.
17 |
18 | ### Bugs
19 | If you find a 🐞 or an issue, please [create an issue](https://github.com/analogwp/stag-blocks/issues/new).
20 |
--------------------------------------------------------------------------------
/assets/img/analog.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/assets/img/blocks.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/assets/img/elementor.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/assets/img/gopro_frames.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/assets/img/gopro_frames.png
--------------------------------------------------------------------------------
/assets/img/placeholder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/img/triangle.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/assets/js/admin.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $('.analog-notice').on( 'click', 'button.notice-dismiss', function(){
3 | $.post( ajaxurl, {
4 | action: 'analog_set_admin_notice_viewed',
5 | key: $( this ).closest('.analog-notice').data( 'key' ),
6 | nonce: AnalogAdmin.nonce || '',
7 | } );
8 |
9 | console.log($( this ).closest('.analog-notice').data( 'key' ));
10 | } );
11 | })(jQuery);
12 |
--------------------------------------------------------------------------------
/assets/js/elementor-modal.js:
--------------------------------------------------------------------------------
1 | /* global elementor, elementorCommon */
2 | /* eslint-disable */
3 |
4 | const analog = window.analog = window.analog || {};
5 |
6 | "undefined" != typeof jQuery &&
7 | !(function($) {
8 | $(function() {
9 | function modal() {
10 | const insertIndex = 0 < jQuery(this).parents(".elementor-section-wrap").length ? jQuery(this).parents(".elementor-add-section").index() : -1;
11 |
12 | analog.insertIndex = insertIndex;
13 |
14 | elementorCommon &&
15 | (window.analogModal ||
16 | ((window.analogModal = elementorCommon.dialogsManager.createWidget(
17 | "lightbox",
18 | {
19 | id: "analogwp-templates-modal",
20 | headerMessage: "What is this???",
21 | message: "",
22 | hide: {
23 | auto: !1,
24 | onClick: !1,
25 | onOutsideClick: !1,
26 | onOutsideContextMenu: !1,
27 | onBackgroundClick: !0
28 | },
29 | position: {
30 | my: "center",
31 | at: "center"
32 | },
33 | onShow: function() {
34 | const content = window.analogModal.getElements("content");
35 | content.append('
{
76 | const { theme } = React.useContext( ThemeContext );
77 |
78 | return (
79 |
80 |
81 |
82 |

83 |
84 | { ! AGWP.isContainer &&
}
85 |
86 |
87 |
88 | );
89 | };
90 |
91 | export default Header;
92 |
--------------------------------------------------------------------------------
/client/Modal.js:
--------------------------------------------------------------------------------
1 | import styled, { keyframes } from 'styled-components';
2 | const { FocusableIframe, Button } = wp.components;
3 | const { __ } = wp.i18n;
4 |
5 | const rotateOpacity = keyframes`
6 | 0% {
7 | opacity: 0.5;
8 | }
9 |
10 | 50% {
11 | opacity: 0.1;
12 | }
13 |
14 | 100% {
15 | opacity: 0.5;
16 | }
17 | `;
18 |
19 | const Img = styled.img`
20 | opacity: 0.5;
21 | transition: all 200ms ease-in-out;
22 | animation: ${ rotateOpacity } 2s linear infinite;
23 | `;
24 |
25 | const Container = styled.div`
26 | position: absolute;
27 | top: 0;
28 | left: 0;
29 | width: 100%;
30 | height: 100%;
31 | overflow: hidden;
32 | overflow: -moz-scrollbars-none;
33 | background: #F1F1F1;
34 | z-index: 999;
35 | text-align: center;
36 |
37 | iframe {
38 | width: 100%;
39 | height: 100%;
40 | display: ${ props => props.loading ? 'none' : 'block' };
41 | }
42 |
43 | .frame-header {
44 | display: flex;
45 | justify-content: space-between;
46 | align-items: center;
47 | margin-bottom: 25px;
48 |
49 | a {
50 | margin-left: auto;
51 | margin-right: 20px;
52 | color: currentColor;
53 | text-decoration: none;
54 | }
55 |
56 | .dashicons {
57 | font-size: 25px;
58 | }
59 | }
60 |
61 | .button--accent {
62 | font-size: 12px;
63 | font-weight: bold;
64 | color: #fff;
65 | border-radius: 0;
66 | border: none;
67 | background: var(--ang-accent);
68 | outline: 0;
69 | box-shadow: none;
70 | padding: 15px 30px;
71 | cursor: pointer;
72 | }
73 | `;
74 |
75 | const Modal = props => {
76 | const [ loading, setLoading ] = React.useState( true );
77 |
78 | return (
79 |
80 |
97 |
98 | { loading &&
}
102 |
103 | setLoading( false ) } />
104 |
105 | );
106 | };
107 |
108 | export default Modal;
109 |
--------------------------------------------------------------------------------
/client/Nav.js:
--------------------------------------------------------------------------------
1 | import AnalogContext from './AnalogContext';
2 | const { __ } = wp.i18n;
3 | const { TabPanel } = wp.components;
4 |
5 | const ITEMS = [
6 | { key: 'blocks', label: AGWP.isContainer ? __( 'Patterns', 'ang' ) : __( 'Blocks', 'ang' ) },
7 | { key: 'templates', label: __( 'Templates', 'ang' ) },
8 | // dont change the "styleKits" casing here
9 | { key: 'styleKits', label: __( 'Styles', 'ang' ) },
10 | ];
11 |
12 | const Nav = () => {
13 | const context = React.useContext( AnalogContext );
14 |
15 | const getCount = ( tab ) => {
16 | let items = context.state[ tab ];
17 |
18 | if ( tab === 'templates' ) {
19 | items = context.state.archive;
20 | }
21 | if ( tab === 'blocks' ) {
22 | items = context.state.blockArchive;
23 | }
24 |
25 | if ( ! items ) {
26 | return false;
27 | }
28 |
29 | return items.length;
30 | };
31 |
32 | const titleGenerator = (titleObject) => {
33 | let count = getCount(titleObject.key);
34 | let countTemplate = count > 0 ? '(' + count + ')' : '';
35 |
36 | return `${titleObject.label} ${countTemplate}`;
37 | }
38 |
39 | const onSelect = ( tabName ) => {
40 | context.dispatch( { tab: tabName });
41 | };
42 |
43 | const tabsGenerator = (tabsArray) => {
44 | return tabsArray.map( (item) => ({
45 | name: item.key,
46 | title: titleGenerator(item),
47 | className: `tab-${ item.key }`
48 | }
49 | ));
50 | }
51 |
52 | const tabContent = () => {
53 | return null;
54 | }
55 |
56 | return (
57 |
58 |
61 | {
62 | (tab) => tabContent()
63 | }
64 |
65 |
66 | );
67 | };
68 |
69 | export default Nav;
70 |
--------------------------------------------------------------------------------
/client/ProModal.js:
--------------------------------------------------------------------------------
1 | const { ExternalLink, Button } = wp.components;
2 | const { __ } = wp.i18n;
3 |
4 | const ProModal = () => (
5 |
9 | );
10 |
11 | export default ProModal;
12 |
--------------------------------------------------------------------------------
/client/Synchronization.js:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import AnalogContext from './AnalogContext';
3 | import { NotificationConsumer } from './Notifications';
4 | import Close from './icons/close';
5 |
6 | const { __ } = wp.i18n;
7 | const { Button } = wp.components;
8 |
9 | const Synchronization = () => {
10 | return (
11 |
12 |
13 | { context => (
14 |
15 | { ( { add } ) => (
16 |
32 | ) }
33 |
34 | ) }
35 |
36 | { ! AGWP.is_settings_page && (
37 |
40 | ) }
41 |
42 | );
43 | };
44 |
45 | export default Synchronization;
46 |
--------------------------------------------------------------------------------
/client/Template.js:
--------------------------------------------------------------------------------
1 | import classnames from 'classnames';
2 | import Image from './helpers/Image';
3 | import Star from './icons/star';
4 | import { isNewTheme } from './utils';
5 |
6 | const { decodeEntities } = wp.htmlEntities;
7 | const { __ } = wp.i18n;
8 | const { Button, Card, CardBody, CardFooter } = wp.components;
9 |
10 | const Template = ( { template, setModalContent, importLayout, favorites, makeFavorite } ) => {
11 | const isValid = ( isPro ) => ! ( isPro && AGWP.license.status !== 'valid' );
12 |
13 | const fallbackImage = AGWP.pluginURL + 'assets/img/placeholder.svg';
14 |
15 | return (
16 |
17 |
18 |
19 | { ( isNewTheme( template.published ) > -14 ) && (
20 | { __( 'New', 'ang' ) }
21 | ) }
22 |
23 |
24 | { template.thumbnail ? :
}
25 |
26 |
29 | { ! isValid( template.is_pro ) && (
30 |
31 |
32 |
33 | ) }
34 | { isValid( template.is_pro ) && (
35 |
38 | ) }
39 |
40 |
41 |
49 |
50 |
51 |
52 |
53 |
54 | { decodeEntities( template.title ) }
55 | { template.tags && (
56 |
57 | { template.tags.map( tag => (
58 | { tag }
59 | ) ) }
60 |
61 | ) }
62 |
63 | { template.is_pro && (
64 |
{ __( 'Pro', 'ang' ) }
65 | ) }
66 |
67 |
68 |
69 |
70 | );
71 | };
72 |
73 | export default Template;
74 |
--------------------------------------------------------------------------------
/client/contexts/ThemeContext.js:
--------------------------------------------------------------------------------
1 | const ThemeContext = React.createContext();
2 |
3 | export const ThemeProvider = ThemeContext.Provider;
4 | export const ThemeConsumer = ThemeContext.Consumer;
5 |
6 | export const Theme = {
7 | accent: 'var(--ang-primary)',
8 | textLight: 'var(--ang-sec-text)',
9 | textDark: 'var(--ang-main-text)',
10 | lightGray: '#F2F2F2',
11 | };
12 |
13 | export default ThemeContext;
14 |
--------------------------------------------------------------------------------
/client/helpers/Empty.js:
--------------------------------------------------------------------------------
1 | const Empty = ( { text = 'No templates found.', ...rest } ) => {
2 | return (
3 |
6 | );
7 | };
8 |
9 | export default Empty;
10 |
--------------------------------------------------------------------------------
/client/helpers/Image.js:
--------------------------------------------------------------------------------
1 | import { Waypoint } from 'react-waypoint';
2 |
3 | const Image = ( { template, ...attributes } ) => {
4 | const { thumbnail, title } = template;
5 | const [ image, setImage ] = React.useState( AGWP.pluginURL + 'assets/img/placeholder.svg' );
6 |
7 | return (
8 |
{
9 | setImage( thumbnail );
10 | } }>
11 |
12 |
13 | );
14 | };
15 |
16 | export default Image;
17 |
--------------------------------------------------------------------------------
/client/icons/close.js:
--------------------------------------------------------------------------------
1 | const Close = () => (
2 |
11 | );
12 |
13 | export default Close;
14 |
--------------------------------------------------------------------------------
/client/icons/error.js:
--------------------------------------------------------------------------------
1 | const Error = () => (
2 |
5 | );
6 |
7 | export default Error;
8 |
--------------------------------------------------------------------------------
/client/icons/loader.js:
--------------------------------------------------------------------------------
1 | const Loader = () => (
2 |
3 | );
4 |
5 | export default Loader;
6 |
--------------------------------------------------------------------------------
/client/icons/notice.js:
--------------------------------------------------------------------------------
1 | const Notice = () => (
2 |
5 | );
6 |
7 | export default Notice;
--------------------------------------------------------------------------------
/client/icons/refresh.js:
--------------------------------------------------------------------------------
1 | const Refresh = () => (
2 |
14 | );
15 |
16 | export default Refresh;
17 |
--------------------------------------------------------------------------------
/client/icons/star.js:
--------------------------------------------------------------------------------
1 | const Star = () => (
2 |
11 | );
12 |
13 | export default Star;
14 |
--------------------------------------------------------------------------------
/client/icons/success.js:
--------------------------------------------------------------------------------
1 | const Success = () => (
2 |
5 | );
6 |
7 | export default Success;
8 |
--------------------------------------------------------------------------------
/client/index.js:
--------------------------------------------------------------------------------
1 | import App from './App';
2 |
3 | const containerElementID = 'analogwp-templates';
4 |
5 | const waitForEl = ( selector, callback ) => {
6 | if ( ! document.getElementById( containerElementID ) ) {
7 | setTimeout( function() {
8 | window.requestAnimationFrame( function() {
9 | waitForEl( selector, callback );
10 | } );
11 | }, 1000 );
12 | } else {
13 | callback();
14 | }
15 | };
16 |
17 | // We don't use a variable here because in Elementor modal the element is added dynamically.
18 | waitForEl( document.getElementById( containerElementID ), () => {
19 | if ( window.AGWP && window.AGWP.wp_version && window.AGWP.wp_version >= '6.2' ) {
20 | const { createRoot } = wp.element;
21 | const containerRoot = createRoot( document.getElementById( containerElementID ) );
22 | containerRoot.render(
);
23 | } else {
24 | // Ensure compatibility with React 17 and lower.
25 | const { render } = wp.element;
26 | render(
, document.getElementById( containerElementID ) );
27 | }
28 | } );
29 |
--------------------------------------------------------------------------------
/client/popup.js:
--------------------------------------------------------------------------------
1 | import Close from './icons/close';
2 |
3 | const { Card, CardBody, CardDivider, CardHeader } = wp.components;
4 |
5 | const Popup = ( props ) => {
6 | const { title, onRequestClose, children, ...rest } = props;
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
{ title }
14 | { onRequestClose && (
15 |
18 | ) }
19 |
20 |
21 |
22 |
23 |
24 | { children }
25 |
26 |
27 |
28 |
29 |
30 | );
31 | };
32 |
33 | export default Popup;
34 |
--------------------------------------------------------------------------------
/client/utils.js:
--------------------------------------------------------------------------------
1 | import { requestSettingUpdate } from './api';
2 | import Filters from './filters';
3 | import StyleKits from './stylekits/stylekits';
4 | import Blocks from './blocks/blocks';
5 | import Templates from './Templates';
6 |
7 | const { Fragment } = React;
8 |
9 | export const getPageComponents = ( state ) => {
10 | if ( state.tab === 'styleKits' ) {
11 | return
;
12 | }
13 |
14 | if ( state.tab === 'blocks' ) {
15 | return
;
16 | }
17 |
18 | return (
19 |
20 | { ! state.isOpen && }
21 |
22 |
23 | );
24 | };
25 |
26 | export const debugMode = () => Boolean( AGWP.debugMode );
27 |
28 | export const Log = ( what ) => {
29 | if ( debugMode ) {
30 | console.log( what ); // eslint-disable-line
31 | }
32 | };
33 | export const LogStart = ( title ) => {
34 | if ( debugMode ) {
35 | console.group( title ); // eslint-disable-line
36 | }
37 | };
38 | export const LogEnd = ( title ) => {
39 | if ( debugMode ) {
40 | console.groupEnd( title ); // eslint-disable-line
41 | }
42 | };
43 |
44 | export function generateUEID() {
45 | let first = ( Math.random() * 46656 ) || 0;
46 | let second = ( Math.random() * 46656 ) || 0;
47 | first = ( '000' + first.toString( 36 ) ).slice( -3 );
48 | second = ( '000' + second.toString( 36 ) ).slice( -3 );
49 | return first + second;
50 | }
51 |
52 | export function hasProTemplates( templates ) {
53 | return templates.some( ( template ) => template.is_pro === true );
54 | }
55 |
56 | export function increaseInstallCount( settings, dispatch ) {
57 | const installCount = parseInt( settings.install_count ) || 0;
58 |
59 | dispatch( {
60 | settings: {
61 | ...settings,
62 | install_count: installCount + 1,
63 | },
64 | } );
65 |
66 | requestSettingUpdate( 'install_count', installCount + 1 );
67 | }
68 |
69 | export function isNewTheme( date ) {
70 | const start = moment.unix( date );
71 | const end = moment.now();
72 | return Math.ceil( moment.duration( start.diff( end ) ).asDays() );
73 | }
74 |
75 | export function getTime( date ) {
76 | const start = moment.unix( date );
77 | const end = moment.now();
78 | return Math.ceil( moment.duration( start.diff( end ) ).asMinutes() );
79 | }
80 |
--------------------------------------------------------------------------------
/codeception.dist.yml:
--------------------------------------------------------------------------------
1 | paths:
2 | tests: tests
3 | output: tests/_output
4 | data: tests/_data
5 | support: tests/_support
6 | envs: tests/_envs
7 | actor_suffix: Tester
8 | extensions:
9 | enabled:
10 | - Codeception\Extension\RunFailed
11 | commands:
12 | - Codeception\Command\GenerateWPUnit
13 | - Codeception\Command\GenerateWPRestApi
14 | - Codeception\Command\GenerateWPRestController
15 | - Codeception\Command\GenerateWPRestPostTypeController
16 | - Codeception\Command\GenerateWPAjax
17 | - Codeception\Command\GenerateWPCanonical
18 | - Codeception\Command\GenerateWPXMLRPC
19 | - Codeception\Command\DbSnapshot
20 | - tad\Codeception\Command\SearchReplace
21 | params:
22 | - .env
23 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "analogwp/analogwp-templates",
3 | "description": "Style Kits for Elementor adds a number of intuitive styling controls in the Elementor editor that allow you to apply styles globally or per page.",
4 | "type": "wordpress-plugin",
5 | "license": "GPL-2.0",
6 | "authors": [
7 | {
8 | "name": "AnalogWP",
9 | "email": "hello@analogwp.com"
10 | }
11 | ],
12 | "minimum-stability": "dev",
13 | "prefer-stable": true,
14 | "config": {
15 | "sort-packages": true,
16 | "allow-plugins": {
17 | "civicrm/composer-downloads-plugin": true,
18 | "ergebnis/composer-normalize": true
19 | }
20 | },
21 | "require": {
22 | "enshrined/svg-sanitize": "^0.15.4"
23 | },
24 | "require-dev": {
25 | "civicrm/composer-downloads-plugin": "*",
26 | "ergebnis/composer-normalize": "*",
27 | "flow/jsonpath": "*",
28 | "sniccowp/php-scoper-wordpress-excludes": "*"
29 | },
30 | "extra": {
31 | "downloads": {
32 | "php-scoper": {
33 | "path": "vendor/bin/php-scoper",
34 | "type": "phar",
35 | "url": "https://github.com/humbug/php-scoper/releases/download/0.17.2/php-scoper.phar"
36 | }
37 | }
38 | },
39 | "scripts": {
40 | "post-install-cmd": [
41 | "@prefix-dependencies"
42 | ],
43 | "post-update-cmd": [
44 | "@prefix-dependencies"
45 | ],
46 | "prefix-dependencies": [
47 | "php-scoper add-prefix --output-dir=./third-party --force --quiet",
48 | "echo '{ \"autoload\": { \"classmap\": [\"\"] } }' > ./third-party/composer.json",
49 | "@composer dump-autoload --working-dir ./third-party --no-dev --classmap-authoritative"
50 | ]
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/freemius/assets/css/admin/affiliation.css:
--------------------------------------------------------------------------------
1 | #fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;margin-left:0;padding:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";font-weight:700;margin-right:10px}#fs_affiliation_content_wrapper label,#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper p:not(.description){font-size:16px!important;line-height:26px!important}#fs_affiliation_content_wrapper .button{font-size:16px;height:40px;line-height:35px;margin-bottom:7px;margin-top:20px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{display:block;font-weight:700;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{display:inline-block;margin-top:3px;text-decoration:none}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
--------------------------------------------------------------------------------
/freemius/assets/css/admin/checkout.css:
--------------------------------------------------------------------------------
1 | .fs-ajax-loader{height:20px;margin:auto;position:relative;width:170px}.fs-ajax-loader .fs-ajax-loader-bar{animation-direction:normal;animation-duration:1.5s;animation-iteration-count:infinite;animation-name:bounce_ajaxLoader;background-color:#fff;height:20px;position:absolute;top:0;transform:scale(.3);width:20px}.fs-ajax-loader .fs-ajax-loader-bar-1{animation-delay:.6s;left:0}.fs-ajax-loader .fs-ajax-loader-bar-2{animation-delay:.75s;left:19px}.fs-ajax-loader .fs-ajax-loader-bar-3{animation-delay:.9s;left:38px}.fs-ajax-loader .fs-ajax-loader-bar-4{animation-delay:1.05s;left:57px}.fs-ajax-loader .fs-ajax-loader-bar-5{animation-delay:1.2s;left:76px}.fs-ajax-loader .fs-ajax-loader-bar-6{animation-delay:1.35s;left:95px}.fs-ajax-loader .fs-ajax-loader-bar-7{animation-delay:1.5s;left:114px}.fs-ajax-loader .fs-ajax-loader-bar-8{animation-delay:1.65s;left:133px}@keyframes bounce_ajaxLoader{0%{background-color:#0074a3;transform:scale(1)}to{background-color:#fff;transform:scale(.3)}}@media screen and (max-width:782px){#wpbody-content{padding-bottom:0!important}}.fs-checkout-process-redirect{padding:40px;text-align:center}
--------------------------------------------------------------------------------
/freemius/assets/css/admin/clone-resolution.css:
--------------------------------------------------------------------------------
1 | .fs-notice[data-id^=clone_resolution_options_notice]{color:inherit!important;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{margin-bottom:0;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-bottom:0;margin-top:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width:750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;flex:auto;margin:5px;padding:10px 10px 15px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;line-height:1.5em;padding:2px}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-left:10px;margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{background:#fee;border:1px solid #d3135a;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}.fs-notice[data-id=temporary_duplicate_notice] a{position:relative}.fs-notice[data-id=temporary_duplicate_notice] a:focus{box-shadow:none}.fs-notice[data-id=temporary_duplicate_notice] a.disabled{color:gray}.fs-notice[data-id=temporary_duplicate_notice] a .fs-ajax-spinner{bottom:0;left:8px;margin-left:100%;position:absolute;right:0;top:-1px}
--------------------------------------------------------------------------------
/freemius/assets/css/admin/debug.css:
--------------------------------------------------------------------------------
1 | label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:700}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac!important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
--------------------------------------------------------------------------------
/freemius/assets/css/admin/gdpr-optin-notice.css:
--------------------------------------------------------------------------------
1 | .fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description,.fs-notice[data-id^=gdpr_optin_actions] ul .button{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px}
--------------------------------------------------------------------------------
/freemius/assets/css/admin/index.php:
--------------------------------------------------------------------------------
1 | ").attr({method:t,action:r}).css({display:"none"}),a=function(r,e){if(n.isArray(e))for(var t=0;t
").attr({type:"hidden",name:String(r),value:String(e)}))};for(var i in e)e.hasOwnProperty(i)&&a(i,e[i]);return o.appendTo("body")}})}(jQuery);
--------------------------------------------------------------------------------
/freemius/assets/js/nojquery.ba-postmessage.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery postMessage - v0.5 - 9/11/2009
3 | * http://benalman.com/projects/jquery-postmessage-plugin/
4 | *
5 | * Copyright (c) 2009 "Cowboy" Ben Alman
6 | * Dual licensed under the MIT and GPL licenses.
7 | * http://benalman.com/about/license/
8 | *
9 | * Non-jQuery fork by Jeff Lee
10 | *
11 | * This fork consists of the following changes:
12 | * 1. Basic code cleanup and restructuring, for legibility.
13 | * 2. The `postMessage` and `receiveMessage` functions can be bound arbitrarily,
14 | * in terms of both function names and object scope. Scope is specified by
15 | * the the "this" context of NoJQueryPostMessageMixin();
16 | * 3. I've removed the check for Opera 9.64, which used `$.browser`. There were
17 | * at least three different GitHub users requesting the removal of this
18 | * "Opera sniff" on the original project's Issues page, so I figured this
19 | * would be a relatively safe change.
20 | * 4. `postMessage` no longer uses `$.param` to serialize messages that are not
21 | * strings. I actually prefer this structure anyway. `receiveMessage` does
22 | * not implement a corresponding deserialization step, and as such it seems
23 | * cleaner and more symmetric to leave both data serialization and
24 | * deserialization to the client.
25 | * 5. The use of `$.isFunction` is replaced by a functionally-identical check.
26 | * 6. The `$:nomunge` YUI option is no longer necessary.
27 | */
28 | function NoJQueryPostMessageMixin(n,e){var t,i,o,s,a,r=1;return window.postMessage?(window.addEventListener?(t=function(n){window.addEventListener("message",n,!1)},i=function(n){window.removeEventListener("message",n,!1)}):(t=function(n){window.attachEvent("onmessage",n)},i=function(n){window.detachEvent("onmessage",n)}),this[n]=function(n,e,t){e&&t.postMessage(n,e.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))},this[e]=function(n,e,s){if(o&&(i(o),o=null),!n)return!1;o=t((function(t){switch(Object.prototype.toString.call(e)){case"[object String]":if(e!==t.origin)return!1;break;case"[object Function]":if(e(t.origin))return!1}n(t)}))}):(this[n]=function(n,e,t){e&&(t.location=e.replace(/#.*$/,"")+"#"+ +new Date+r+++"&"+n)},this[e]=function(n,e,t){s&&(clearInterval(s),s=null),n&&(t="number"==typeof e?e:"number"==typeof t?t:100,s=setInterval((function(){var e=document.location.hash,t=/^#?\d+&/;e!==a&&t.test(e)&&(a=e,n({data:e.replace(t,"")}))}),t))}),this}
--------------------------------------------------------------------------------
/freemius/assets/js/postmessage.js:
--------------------------------------------------------------------------------
1 | !function(e,t){var s,n,o,i,r,a,c,p,u=this;u.FS=u.FS||{},u.FS.PostMessage=(n=new NoJQueryPostMessageMixin("postMessage","receiveMessage"),o={},i=decodeURIComponent(document.location.hash.replace(/^#/,"")),r=i.substring(0,i.indexOf("/","https://"===i.substring(0,8)?8:7)),a=""!==i,c=e(window),p=e("html"),{init:function(e,t){s=e,n.receiveMessage((function(e){var t=JSON.parse(e.data);if(o[t.type])for(var s=0;s0&&c.on("scroll",(function(){for(var e=0;e
11 | * @license MIT
12 | */
13 |
14 | /*!
15 | * Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com
16 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
17 | * Copyright 2022 Fonticons, Inc.
18 | */
19 |
20 | /** @license React v0.20.2
21 | * scheduler.production.min.js
22 | *
23 | * Copyright (c) Facebook, Inc. and its affiliates.
24 | *
25 | * This source code is licensed under the MIT license found in the
26 | * LICENSE file in the root directory of this source tree.
27 | */
28 |
29 | /** @license React v17.0.2
30 | * react-dom.production.min.js
31 | *
32 | * Copyright (c) Facebook, Inc. and its affiliates.
33 | *
34 | * This source code is licensed under the MIT license found in the
35 | * LICENSE file in the root directory of this source tree.
36 | */
37 |
38 | /** @license React v17.0.2
39 | * react.production.min.js
40 | *
41 | * Copyright (c) Facebook, Inc. and its affiliates.
42 | *
43 | * This source code is licensed under the MIT license found in the
44 | * LICENSE file in the root directory of this source tree.
45 | */
46 |
--------------------------------------------------------------------------------
/freemius/includes/class-fs-user-lock.php:
--------------------------------------------------------------------------------
1 | _lock = new FS_Lock( "locked_{$current_user_id}" );
53 | }
54 |
55 | /**
56 | * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything.
57 | *
58 | * @author Vova Feldman (@svovaf)
59 | * @since 2.1.0
60 | *
61 | * @param int $expiration
62 | *
63 | * @return bool TRUE if successfully acquired lock.
64 | */
65 | function try_lock( $expiration = 0 ) {
66 | return $this->_lock->try_lock( $expiration );
67 | }
68 |
69 | /**
70 | * Acquire lock regardless if it's already acquired by another locker or not.
71 | *
72 | * @author Vova Feldman (@svovaf)
73 | * @since 2.1.0
74 | *
75 | * @param int $expiration
76 | */
77 | function lock( $expiration = 0 ) {
78 | $this->_lock->lock( $expiration );
79 | }
80 |
81 | /**
82 | * Unlock the lock.
83 | *
84 | * @author Vova Feldman (@svovaf)
85 | * @since 2.1.0
86 | */
87 | function unlock() {
88 | $this->_lock->unlock();
89 | }
90 | }
--------------------------------------------------------------------------------
/freemius/includes/customizer/index.php:
--------------------------------------------------------------------------------
1 | title( 'Freemius' ); // @phpstan-ignore-line
27 | }
28 |
29 | public static function requests_count() {
30 | if ( class_exists( 'Freemius_Api_WordPress' ) ) {
31 | $logger = Freemius_Api_WordPress::GetLogger();
32 | } else {
33 | $logger = array();
34 | }
35 |
36 | return number_format( count( $logger ) );
37 | }
38 |
39 | public static function total_time() {
40 | if ( class_exists( 'Freemius_Api_WordPress' ) ) {
41 | $logger = Freemius_Api_WordPress::GetLogger();
42 | } else {
43 | $logger = array();
44 | }
45 |
46 | $total_time = .0;
47 | foreach ( $logger as $l ) {
48 | $total_time += $l['total'];
49 | }
50 |
51 | return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
52 | }
53 |
54 | public function render() {
55 | ?>
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | status );
47 | }
48 |
49 | /**
50 | * @author Leo Fajardo
51 | *
52 | * @return bool
53 | */
54 | function is_pending() {
55 | return ( 'pending' === $this->status );
56 | }
57 |
58 | /**
59 | * @author Leo Fajardo
60 | *
61 | * @return bool
62 | */
63 | function is_suspended() {
64 | return ( 'suspended' === $this->status );
65 | }
66 |
67 | /**
68 | * @author Leo Fajardo
69 | *
70 | * @return bool
71 | */
72 | function is_rejected() {
73 | return ( 'rejected' === $this->status );
74 | }
75 |
76 | /**
77 | * @author Leo Fajardo
78 | *
79 | * @return bool
80 | */
81 | function is_blocked() {
82 | return ( 'blocked' === $this->status );
83 | }
84 | }
--------------------------------------------------------------------------------
/freemius/includes/entities/class-fs-billing.php:
--------------------------------------------------------------------------------
1 | release_mode );
63 | }
64 | }
--------------------------------------------------------------------------------
/freemius/includes/entities/class-fs-scope-entity.php:
--------------------------------------------------------------------------------
1 | is_beta );
61 | }
62 | }
63 |
64 | function get_name() {
65 | return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
66 | }
67 |
68 | function is_verified() {
69 | return ( isset( $this->is_verified ) && true === $this->is_verified );
70 | }
71 |
72 | /**
73 | * @author Leo Fajardo (@leorw)
74 | * @since 2.4.2
75 | *
76 | * @return bool
77 | */
78 | function is_beta() {
79 | // Return `false` since this is just for backward compatibility.
80 | return false;
81 | }
82 |
83 | static function get_type() {
84 | return 'user';
85 | }
86 | }
--------------------------------------------------------------------------------
/freemius/includes/entities/index.php:
--------------------------------------------------------------------------------
1 |
44 | */
45 | public function get_query_params( Freemius $fs ) {
46 | $context_params = array(
47 | 'plugin_id' => $fs->get_id(),
48 | 'plugin_public_key' => $fs->get_public_key(),
49 | 'plugin_version' => $fs->get_plugin_version(),
50 | );
51 |
52 | // Get site context secure params.
53 | if ( $fs->is_registered() ) {
54 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params(
55 | $fs->get_site(),
56 | time(),
57 | 'contact'
58 | ) );
59 | }
60 |
61 | return array_merge( $_GET, array_merge( $context_params, array(
62 | 'plugin_version' => $fs->get_plugin_version(),
63 | 'wp_login_url' => wp_login_url(),
64 | 'site_url' => Freemius::get_unfiltered_site_url(),
65 | // 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons",
66 | ) ) );
67 | }
68 |
69 | /**
70 | * Retrieves the standalone link to the Freemius Contact Form.
71 | *
72 | * @param Freemius $fs
73 | *
74 | * @return string
75 | */
76 | public function get_standalone_link( Freemius $fs ) {
77 | $query_params = $this->get_query_params( $fs );
78 |
79 | $query_params['is_standalone'] = 'true';
80 | $query_params['parent_url'] = admin_url( add_query_arg( null, null ) );
81 |
82 | return WP_FS__ADDRESS . '/contact/?' . http_build_query( $query_params );
83 | }
84 | }
--------------------------------------------------------------------------------
/freemius/includes/managers/index.php:
--------------------------------------------------------------------------------
1 | _result = $result;
23 |
24 | $code = 0;
25 | $message = 'Unknown error, please check GetResult().';
26 | $type = '';
27 |
28 | if ( isset( $result['error'] ) && is_array( $result['error'] ) ) {
29 | if ( isset( $result['error']['code'] ) ) {
30 | $code = $result['error']['code'];
31 | }
32 | if ( isset( $result['error']['message'] ) ) {
33 | $message = $result['error']['message'];
34 | }
35 | if ( isset( $result['error']['type'] ) ) {
36 | $type = $result['error']['type'];
37 | }
38 | }
39 |
40 | $this->_type = $type;
41 | $this->_code = $code;
42 |
43 | parent::__construct( $message, is_numeric( $code ) ? $code : 0 );
44 | }
45 |
46 | /**
47 | * Return the associated result object returned by the API server.
48 | *
49 | * @return array The result from the API server
50 | */
51 | public function getResult() {
52 | return $this->_result;
53 | }
54 |
55 | public function getStringCode() {
56 | return $this->_code;
57 | }
58 |
59 | public function getType() {
60 | return $this->_type;
61 | }
62 |
63 | /**
64 | * To make debugging easier.
65 | *
66 | * @return string The string representation of the error
67 | */
68 | public function __toString() {
69 | $str = $this->getType() . ': ';
70 |
71 | if ( $this->code != 0 ) {
72 | $str .= $this->getStringCode() . ': ';
73 | }
74 |
75 | return $str . $this->getMessage();
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/freemius/includes/sdk/Exceptions/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 | $data ) {
35 | if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) . '/' ) ) ) {
36 | if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) {
37 | return $relative_path;
38 | }
39 | }
40 | }
41 |
42 | return null;
43 | }
44 |
--------------------------------------------------------------------------------
/freemius/includes/supplements/fs-essential-functions-2.2.1.php:
--------------------------------------------------------------------------------
1 | $install ) {
21 | if ( true === $install->is_disconnected ) {
22 | $permission_manager->update_site_tracking(
23 | false,
24 | ( 0 == $blog_id ) ? null : $blog_id,
25 | // Update only if permissions are not yet set.
26 | true
27 | );
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/freemius/includes/supplements/index.php:
--------------------------------------------------------------------------------
1 |
35 |
--------------------------------------------------------------------------------
/freemius/templates/account/partials/deactivate-license-button.php:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/freemius/templates/account/partials/index.php:
--------------------------------------------------------------------------------
1 | get_slug();
25 |
26 | ?>
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | |
36 | |
37 | |
38 | |
39 |
40 |
41 |
42 |
43 |
44 | >
45 | id ?> |
46 | created ) ) ?> |
47 | formatted_gross() ?> |
48 | is_migrated() ) : ?> |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
21 |
--------------------------------------------------------------------------------
/freemius/templates/ajax-loader.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/freemius/templates/api-connectivity-message-js.php:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/freemius/templates/checkout.php:
--------------------------------------------------------------------------------
1 | is_premium() ) {
23 | fs_require_template( 'checkout/frame.php', $VARS );
24 | } else {
25 | fs_require_template( 'checkout/redirect.php', $VARS );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/freemius/templates/connect/index.php:
--------------------------------------------------------------------------------
1 |
29 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
class="fs-tooltip-trigger">
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/freemius/templates/debug/index.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 | # |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 |
28 |
29 |
30 |
31 |
33 |
39 | >
42 | . |
43 | get_id() ?> |
44 | |
45 |
|
46 |
47 | %s',
50 | esc_html( substr( $log['msg'], 0, 32 ) ) . ( 32 < strlen( $log['msg'] ) ? '...' : '' )
51 | );
52 | ?>
53 |
54 |
55 |
56 | |
57 | get_file() ) . ':' . $log['line'];
60 | }
61 | ?> |
62 | |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/freemius/templates/email.php:
--------------------------------------------------------------------------------
1 |
18 |
19 | $section ) {
21 | ?>
22 |
23 | |
24 |
25 |
26 | $row ) {
28 | $col_count = count( $row );
29 | ?>
30 |
31 |
33 | |
34 |
36 | : |
37 | |
38 |
41 |
42 |
45 |
46 |
49 |
--------------------------------------------------------------------------------
/freemius/templates/forms/deactivation/contact.php:
--------------------------------------------------------------------------------
1 | get_slug();
18 |
19 | 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 )
20 | . sprintf(" %s",
21 | $fs->contact_url( 'technical_support' ),
22 | fs_text_inline( 'Contact Support', 'contact-support', $slug )
23 | );
24 |
--------------------------------------------------------------------------------
/freemius/templates/forms/deactivation/index.php:
--------------------------------------------------------------------------------
1 | get_slug();
18 |
19 | $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' );
20 | $skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) );
21 | $use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug );
22 |
23 | 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}" )
24 | . " {$use_plugin_anonymously_text}";
--------------------------------------------------------------------------------
/freemius/templates/forms/index.php:
--------------------------------------------------------------------------------
1 | _get_license();
19 |
20 | if ( ! is_object( $license ) ) {
21 | $purchase_url = $fs->pricing_url();
22 | } else {
23 | $subscription = $fs->_get_subscription( $license->id );
24 |
25 | $purchase_url = $fs->checkout_url(
26 | is_object( $subscription ) ?
27 | ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) :
28 | WP_FS__PERIOD_LIFETIME,
29 | false,
30 | array( 'licenses' => $license->quota )
31 | );
32 | }
33 |
34 | $plugin_data = $fs->get_plugin_data();
35 | ?>
36 |
--------------------------------------------------------------------------------
/freemius/templates/index.php:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/freemius/templates/js/open-license-activation.php:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/freemius/templates/js/style-premium-theme.php:
--------------------------------------------------------------------------------
1 | get_slug();
21 |
22 | ?>
23 |
--------------------------------------------------------------------------------
/freemius/templates/partials/index.php:
--------------------------------------------------------------------------------
1 |
20 |
21 |
 ?>)
22 |
--------------------------------------------------------------------------------
/freemius/templates/plugin-info/description.php:
--------------------------------------------------------------------------------
1 | info->selling_point_0 ) ||
21 | ! empty( $plugin->info->selling_point_1 ) ||
22 | ! empty( $plugin->info->selling_point_2 )
23 | ) : ?>
24 |
25 |
26 |
27 | info->{'selling_point_' . $i} ) ) : ?>
28 | -
29 |
30 |
info->{'selling_point_' . $i} ) ?>
31 |
32 |
33 |
34 |
35 |
36 |
37 | info->description, array(
39 | 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
40 | 'b' => array(),
41 | 'i' => array(),
42 | 'p' => array(),
43 | 'blockquote' => array(),
44 | 'h2' => array(),
45 | 'h3' => array(),
46 | 'ul' => array(),
47 | 'ol' => array(),
48 | 'li' => array()
49 | ) );
50 | ?>
51 |
52 | info->screenshots ) ) : ?>
53 | info->screenshots ?>
54 |
55 |
slug ) ?>
56 |
57 | $url ) : ?>
59 | -
60 |
66 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/freemius/templates/plugin-info/index.php:
--------------------------------------------------------------------------------
1 |
22 |
23 | $url ) : ?>
25 | -
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/freemius/templates/secure-https-header.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ),
29 | $VARS['page']
30 | ) ) .
31 | ' - ' .
32 | sprintf(
33 | '%s',
34 | 'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION,
35 | 'Freemius Inc. [US]'
36 | );
37 | }
38 | ?>
39 |
--------------------------------------------------------------------------------
/freemius/templates/sticky-admin-notice-js.php:
--------------------------------------------------------------------------------
1 |
16 |
41 |
--------------------------------------------------------------------------------
/freemius/templates/tabs-capture-js.php:
--------------------------------------------------------------------------------
1 | get_slug();
19 | ?>
20 |
--------------------------------------------------------------------------------
/inc/Consumer.php:
--------------------------------------------------------------------------------
1 | parent_base;
39 |
40 | if ( $is_analog_screen ) {
41 | $text = sprintf(
42 | /* translators: 1: Style Kits for Elementor, 2: Link to plugin review */
43 | __( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'ang' ),
44 | '' . __( 'Style Kits for Elementor', 'ang' ) . '',
45 | '★★★★★'
46 | );
47 | }
48 |
49 | return $text;
50 | }
51 |
52 | /**
53 | * Plugin row meta.
54 | *
55 | * Adds row meta links to the plugin list table.
56 | *
57 | * @param array $plugin_meta An array of the plugin's metadata, including the version, author, author URI, and plugin URI.
58 | * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
59 | *
60 | * @return array An array of modified plugin row meta links.
61 | */
62 | public function plugin_row_meta( $plugin_meta, $plugin_file ) {
63 | if ( ANG_PLUGIN_BASE === $plugin_file ) {
64 | $row_meta = array(
65 | 'ang_docs' => '' . __( 'Documentation', 'ang' ) . '',
66 | 'ang_support' => '' . __( 'Get Support', 'ang' ) . '',
67 | );
68 |
69 | $plugin_meta = array_merge( $plugin_meta, $row_meta );
70 | }
71 |
72 | return $plugin_meta;
73 | }
74 | }
75 |
76 | new Admin();
77 |
--------------------------------------------------------------------------------
/inc/class-analog-importer.php:
--------------------------------------------------------------------------------
1 | get_template_content( $args['template_id'], $args['license'], $args['method'], $args['site_id'] );
47 | }
48 |
49 | if ( is_wp_error( $data ) ) {
50 | return $data;
51 | }
52 |
53 | Plugin::elementor()->editor->set_edit_mode( true );
54 |
55 | // Remove Typography options if opted in.
56 | if ( isset( $args['options']['remove_typography'] ) && true === $args['options']['remove_typography'] ) {
57 | require_once ANG_PLUGIN_DIR . 'inc/class-formatter.php';
58 | $data['content'] = Formatter::remove_typography_data_recursive( $data['content'] );
59 | }
60 |
61 | $data['content'] = $this->replace_elements_ids( $data['content'] );
62 | $data['content'] = $this->process_export_import_content( $data['content'], 'on_import' );
63 |
64 | $post_id = $args['editor_post_id'];
65 | $document = Plugin::elementor()->documents->get( $post_id );
66 | if ( $document ) {
67 | $data['content'] = $document->get_elements_raw_data( $data['content'], true );
68 | }
69 |
70 | /**
71 | * During json encode/decode between preview/demo, isInner is usually converted into string.
72 | * This helper function converts it back to Boolean so Elementor doesn't changes this control
73 | * into an "Inner Section".
74 | *
75 | * @since 1.3.8
76 | */
77 | $data['content'] = Utils::convert_string_to_boolean( $data['content'] );
78 |
79 | return $data;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/inc/class-cron.php:
--------------------------------------------------------------------------------
1 | WEEK_IN_SECONDS,
41 | 'display' => __( 'Once Weekly', 'ang' ),
42 | );
43 |
44 | return $schedules;
45 | }
46 |
47 | /**
48 | * Schedules our events
49 | *
50 | * @since 1.1
51 | * @return void
52 | */
53 | public function schedule_events() {
54 | $this->weekly_events();
55 | }
56 |
57 | /**
58 | * Schedule weekly events
59 | *
60 | * @access private
61 | * @since 1.1
62 | * @return void
63 | */
64 | private function weekly_events() {
65 | if ( ! wp_next_scheduled( 'analog/tracker/send_event' ) ) {
66 | wp_schedule_event( time(), 'weekly', 'analog/tracker/send_event' );
67 | }
68 | }
69 | }
70 |
71 |
72 | new Cron();
73 |
--------------------------------------------------------------------------------
/inc/class-formatter.php:
--------------------------------------------------------------------------------
1 | $value ) {
86 | if ( is_array( $haystack ) ) {
87 | $haystack[ $k ] = self::remove_typography_data_recursive( $value );
88 | }
89 | }
90 | }
91 | return $haystack;
92 | }
93 | }
94 |
95 | new Formatter();
96 |
--------------------------------------------------------------------------------
/inc/class-options.php:
--------------------------------------------------------------------------------
1 | get();
59 | $options[ $key ] = $value;
60 | update_option( self::OPTION_KEY, $options );
61 | }
62 |
63 | /**
64 | * Delete a single option.
65 | *
66 | * @param string $key Option key.
67 | * @return void
68 | */
69 | public function delete( $key ) {
70 | $options = $this->get();
71 | if ( ! isset( $options[ $key ] ) ) {
72 | return;
73 | }
74 |
75 | unset( $options[ $key ] );
76 | update_option( self::OPTION_KEY, $options );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/inc/cli/commands.php:
--------------------------------------------------------------------------------
1 | convert_all_sk_to_kits();
19 |
20 | WP_CLI::success( 'All Style Kits have been migrated. 🎉' );
21 | }
22 |
23 | function style_kits_list() {
24 | $posts = \get_posts(
25 | array(
26 | 'post_type' => 'ang_tokens',
27 | 'posts_per_page' => -1,
28 | )
29 | );
30 |
31 | WP_CLI\Utils\format_items( 'table', $posts, array( 'ID', 'post_title' ) );
32 | }
33 |
34 | function kits_list() {
35 | $posts = \get_posts(
36 | array(
37 | 'post_type' => Source_Local::CPT,
38 | 'post_status' => array( 'publish', 'draft' ),
39 | 'posts_per_page' => -1,
40 | 'orderby' => 'title',
41 | 'order' => 'DESC',
42 | 'meta_query' => array( // @codingStandardsIgnoreLine
43 | array(
44 | 'key' => \Elementor\Core\Base\Document::TYPE_META_KEY,
45 | 'value' => 'kit',
46 | ),
47 | ),
48 | )
49 | );
50 |
51 | WP_CLI\Utils\format_items( 'table', $posts, array( 'ID', 'post_title' ) );
52 | }
53 |
54 | function refresh_library() {
55 | delete_transient( 'analogwp_template_info' );
56 |
57 | WP_CLI::success( 'Refresh Style Kit remote library.' );
58 | }
59 |
--------------------------------------------------------------------------------
/inc/elementor/Google_Fonts.php:
--------------------------------------------------------------------------------
1 | 20 ) );
37 |
38 | if ( ! is_wp_error( $request ) ) {
39 | $body = wp_remote_retrieve_body( $request );
40 | if ( ! empty( $body ) ) {
41 | set_transient( self::TRANSIENT, $body, DAY_IN_SECONDS );
42 | }
43 | }
44 | }
45 | }
46 |
47 | /**
48 | * Iterate through our Google fonts library and add it to Elementor.
49 | *
50 | * @param array $additional_fonts Google fonts list.
51 | *
52 | * @since 1.8.0
53 | * @return array|mixed
54 | */
55 | public function add_fonts_to_elementor( $additional_fonts ) {
56 | $fonts = get_transient( self::TRANSIENT );
57 |
58 | if ( $fonts ) {
59 | $fonts = json_decode( $fonts, true );
60 | if ( is_array( $fonts ) && count( $fonts ) ) {
61 | $formatted_fonts = array();
62 |
63 | foreach ( $fonts as $font ) {
64 | $formatted_fonts[ $font ] = 'googlefonts';
65 | }
66 |
67 | $additional_fonts = array_merge( $additional_fonts, $formatted_fonts );
68 | }
69 | }
70 |
71 | return $additional_fonts;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/inc/elementor/Reset_Default_Style_Trait.php:
--------------------------------------------------------------------------------
1 | update_control( $control_id, array( 'default' => $default ) );
34 | }
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/inc/elementor/class-finder-shortcuts.php:
--------------------------------------------------------------------------------
1 | array(
47 | 'title' => __( 'Templates Library', 'ang' ),
48 | 'url' => admin_url( 'admin.php?page=analogwp_templates' ),
49 | 'icon' => 'library-download',
50 | 'keywords' => array( 'analog', 'library', 'settings' ),
51 | ),
52 | 'settings' => array(
53 | 'title' => __( 'Settings', 'ang' ),
54 | 'url' => admin_url( 'admin.php?page=ang-settings' ),
55 | 'icon' => 'settings',
56 | 'keywords' => array( 'analog', 'settings' ),
57 | ),
58 | 'style-kits' => array(
59 | 'title' => __( 'Theme Style Kits', 'ang' ),
60 | 'url' => admin_url( 'admin.php?page=style-kits' ),
61 | 'icon' => 'settings',
62 | 'keywords' => array( 'analog', 'style', 'kits' ),
63 | ),
64 | );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/inc/elementor/class-post-type.php:
--------------------------------------------------------------------------------
1 | __( 'Style Kits', 'ang' ),
33 | 'singular_name' => __( 'Style Kit', 'ang' ),
34 | 'menu_name' => _x( 'Style Kits', 'admin menu', 'ang' ),
35 | 'name_admin_bar' => _x( 'Style Kit', 'add new on admin bar', 'ang' ),
36 | 'add_new' => _x( 'Add New', 'book', 'ang' ),
37 | 'add_new_item' => __( 'Add New Style Kit', 'ang' ),
38 | 'new_item' => __( 'New Style Kit', 'ang' ),
39 | 'edit_item' => __( 'Edit Style Kit', 'ang' ),
40 | 'view_item' => __( 'View Style Kit', 'ang' ),
41 | 'all_items' => __( 'Style Kits', 'ang' ),
42 | 'search_items' => __( 'Search Style Kits', 'ang' ),
43 | 'parent_item_colon' => __( 'Parent Style Kits:', 'ang' ),
44 | 'not_found' => __( 'No Style Kit found.', 'ang' ),
45 | 'not_found_in_trash' => __( 'No Style Kit found in Trash.', 'ang' ),
46 | );
47 | }
48 |
49 | /**
50 | * Register post type.
51 | *
52 | * @return void
53 | */
54 | public function register() {
55 | $args = array(
56 | 'labels' => $this->labels(),
57 | 'hierarchical' => false,
58 | 'show_ui' => apply_filters( 'analog_tokens_visibility', true ),
59 | 'show_in_menu' => false,
60 | 'show_in_nav_menus' => false,
61 | 'show_in_admin_bar' => false,
62 | 'show_admin_column' => false,
63 | 'rewrite' => false,
64 | 'public' => false,
65 | 'supports' => array(
66 | 'title',
67 | 'author',
68 | 'thumbnail',
69 | 'custom-fields',
70 | ),
71 | 'capabilities' => array(
72 | 'create_posts' => 'do_not_allow',
73 | ),
74 | 'map_meta_cap' => true,
75 | );
76 |
77 | $args = apply_filters( 'analog/elementor/cpt/tokens/args', $args, $this->labels() );
78 |
79 | register_post_type( self::CPT, $args );
80 | }
81 | }
82 |
83 | new Post_Type();
84 |
--------------------------------------------------------------------------------
/inc/elementor/globals/class-controller.php:
--------------------------------------------------------------------------------
1 | register_endpoint( new Colors( $this ) );
15 | $this->register_endpoint( new Typography( $this ) );
16 | }
17 |
18 | public function get_collection_params() {
19 | // Does not have 'get_items' args (OPTIONS).
20 | // Maybe TODO: try `$this->get_index_endpoint()->get_collection_params()`.
21 | return [];
22 | }
23 |
24 | public function get_permission_callback( $request ) {
25 | // Allow internal get global values. (e.g render global.css for a visitor)
26 | if ( 'GET' === $request->get_method() && Plugin::elementor()->data_manager_v2->is_internal() ) {
27 | return true;
28 | }
29 |
30 | return current_user_can( 'edit_posts' );
31 | }
32 |
33 | protected function register_index_endpoint() {
34 | $this->register_endpoint( new Endpoint\Index\AllChildren( $this ) );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/inc/elementor/js/ang-cpt-tools.js:
--------------------------------------------------------------------------------
1 | jQuery( document ).ready( function( $ ) {
2 | const ANGTools = function() {
3 | /**
4 | * Hold reusable elements.
5 | *
6 | * @type {Object}
7 | */
8 | const cache = {};
9 |
10 | function init() {
11 | cacheElements();
12 |
13 | initStyleKitImport();
14 | }
15 |
16 | function cacheElements() {
17 | cache.$body = $( 'body' );
18 | cache.$importButton = $( '#analog-import-template-trigger' );
19 | cache.$importArea = $( '#analog-import-template-area' );
20 | }
21 |
22 | function initStyleKitImport() {
23 | if ( ! cache.$body.hasClass( 'post-type-ang_tokens' ) ) {
24 | return;
25 | }
26 |
27 | cache.$formAnchor = $( 'h1.wp-heading-inline' );
28 | cache.$formAnchor.after( cache.$importArea ).after( cache.$importButton );
29 |
30 | cache.$importButton.on( 'click', () => cache.$importArea.toggle() );
31 |
32 | cache.$importArea.find( 'input[type=submit]' ).attr( 'disabled', true );
33 |
34 | cache.$importArea.find( 'input[type=file]' ).on( 'change', function() {
35 | cache.$importArea.find( 'input[type=submit]' ).removeAttr( 'disabled' );
36 | } );
37 | }
38 |
39 | init();
40 | };
41 |
42 | new ANGTools();
43 | } );
44 |
--------------------------------------------------------------------------------
/inc/elementor/js/ang-typography.js:
--------------------------------------------------------------------------------
1 | /* global elementor, ANG_Action, $e, analog */
2 | jQuery( document ).ready( function() {
3 | function handleFonts( font ) {
4 | elementor.helpers.enqueueFont( font );
5 | }
6 |
7 | const pageSettings = elementor.settings.page.model.attributes;
8 | _.map( pageSettings, function( value, key ) {
9 | if ( key.startsWith( 'ang_' ) && key.endsWith( '_font_family' ) ) {
10 | elementor.settings.page.addChangeCallback( key, handleFonts );
11 | }
12 | } );
13 |
14 | elementor.on( 'preview:loaded', () => {
15 | const settings = elementor.settings.page.model.attributes;
16 | _.map( settings, function( value, key ) {
17 | if ( key.startsWith( 'ang_' ) && key.endsWith( '_font_family' ) ) {
18 | if ( value ) {
19 | elementor.helpers.enqueueFont( value );
20 | }
21 | }
22 | } );
23 | } );
24 |
25 | function addPageStyleSettings( groups ) {
26 | const actions = [
27 | {
28 | name: 'page_styles',
29 | title: ANG_Action.translate.pageStyles,
30 | callback: function() {
31 | analog.redirectToSection();
32 | },
33 | },
34 | {
35 | name: 'theme_style',
36 | title: elementor.translate( 'Theme Style' ),
37 | callback: analog.openThemeStyles,
38 | },
39 | {
40 | name: 'global_colors',
41 | title: elementor.translate( 'Edit Style Kit Colors' ),
42 | callback: analog.openGlobalColors,
43 | },
44 | {
45 | name: 'global_fonts',
46 | title: elementor.translate( 'Edit Style Kit Fonts' ),
47 | callback: analog.openGlobalFonts,
48 | },
49 | ];
50 |
51 | const PageStyles = {
52 | name: 'ang_styles',
53 | actions: actions,
54 | };
55 |
56 | groups.splice( 3, 0, PageStyles );
57 | groups.join();
58 |
59 | return groups;
60 | }
61 |
62 | if ( ANG_Action.skPanelsAllowed && elementor.config.initial_document.panel.support_kit ) {
63 | elementor.hooks.addFilter( 'elements/widget/contextMenuGroups', addPageStyleSettings );
64 | elementor.hooks.addFilter( 'elements/section/contextMenuGroups', addPageStyleSettings );
65 | elementor.hooks.addFilter( 'elements/column/contextMenuGroups', addPageStyleSettings );
66 | }
67 | } );
68 |
--------------------------------------------------------------------------------
/inc/elementor/kit/tabs/Theme_Style_Kits.php:
--------------------------------------------------------------------------------
1 | get_id(), $this->get_title() );
29 | }
30 |
31 | /**
32 | * Tab ID.
33 | *
34 | * @return string
35 | */
36 | public function get_id() {
37 | return 'theme-style-kits';
38 | }
39 |
40 | /**
41 | * Tab title.
42 | *
43 | * @return string|void
44 | */
45 | public function get_title() {
46 | return __( 'Style Kits', 'ang' );
47 | }
48 |
49 | /**
50 | * Tab Group.
51 | *
52 | * @return string
53 | */
54 | public function get_group() {
55 | return 'theme-style';
56 | }
57 |
58 | /**
59 | * Tab icon.
60 | *
61 | * @return string
62 | */
63 | public function get_icon() {
64 | return 'eicon-global-settings';
65 | }
66 |
67 | /**
68 | * Tab help URL.
69 | *
70 | * @return string
71 | */
72 | public function get_help_url() {
73 | return 'https://analogwp.com/docs/';
74 | }
75 |
76 | /**
77 | * Tab controls.
78 | *
79 | * Tab controls are hooked mostly on `elementor/element/kit/section_buttons/after_section_end`.
80 | */
81 | protected function register_tab_controls() {}
82 | }
83 |
84 | new Theme_Style_Kits( Kit::class );
85 |
86 | /**
87 | * Fires on tabs registering.
88 | */
89 | add_action(
90 | 'elementor/kit/register_tabs',
91 | function( $kit ) {
92 | $kit->register_tab( 'theme-style-kits', Theme_Style_Kits::class );
93 | }
94 | );
95 |
--------------------------------------------------------------------------------
/inc/elementor/kit/views/trash-kit-confirmation.php:
--------------------------------------------------------------------------------
1 | 'ang_trash_kit',
13 | 'kit_id' => $post_id,
14 | 'ang_trash_kit_nonce' => wp_create_nonce( 'ang_trash_kit' ),
15 | '_wp_http_referrer' => '/wp-admin/admin.php?page=style-kits',
16 | 'force_delete_kit' => '1',
17 | ),
18 | get_admin_url() . 'admin-ajax.php',
19 | );
20 | ?>
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
41 |
42 |
43 |
76 |
--------------------------------------------------------------------------------
/inc/elementor/tags/class-dark-background.php:
--------------------------------------------------------------------------------
1 | editor->is_edit_mode() ) {
39 | $post_id = Plugin::elementor()->editor->get_post_id();
40 | } else {
41 | $post_id = get_the_ID();
42 | }
43 |
44 | return $post_id;
45 | }
46 |
47 | /**
48 | * Get Elementor document type.
49 | *
50 | * @return mixed
51 | */
52 | public function get_document_type() {
53 | $document = Plugin::elementor()->documents->get_doc_or_auto_save( $this->get_post_id() );
54 | if ( $document ) {
55 | $config = $document->get_config();
56 |
57 | return $config['type'];
58 | }
59 |
60 | return false;
61 | }
62 |
63 | /**
64 | * Get a specific Elementor page setting.
65 | *
66 | * @param string $id Setting ID.
67 | *
68 | * @return mixed
69 | */
70 | public function get_page_setting( $id ) {
71 | $page_settings_manager = Manager::get_settings_managers( 'page' );
72 | $page_settings_model = $page_settings_manager->get_model( $this->get_post_id() );
73 |
74 | return $page_settings_model->get_settings( $id );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/inc/settings-helpers.php:
--------------------------------------------------------------------------------
1 | get( $key ) );
91 |
92 | Utils::set_elementor_active_kit( $kit_id );
93 | }
94 | add_action( 'ang_update_option', __NAMESPACE__ . '\ang_update_elementor_kit' );
95 |
--------------------------------------------------------------------------------
/inc/settings/class-settings-experiments.php:
--------------------------------------------------------------------------------
1 | id = 'experiments';
23 | $this->label = __( 'Experiments', 'ang' );
24 | parent::__construct();
25 |
26 | }
27 |
28 | /**
29 | * Get settings array.
30 | *
31 | * @return array
32 | */
33 | public function get_settings() {
34 |
35 | $options = array(
36 | 'default' => __( 'Default', 'ang' ),
37 | 'active' => __( 'Active', 'ang' ),
38 | 'inactive' => __( 'Inactive', 'ang' ),
39 | );
40 |
41 | $settings = apply_filters(
42 | 'ang_experiments_settings',
43 | array(
44 | array(
45 | 'title' => __( 'Style Kits Experiments', 'ang' ),
46 | 'desc' => sprintf(
47 | /* translators: %s: Style Kits Experiments Documentation link */
48 | __( 'Below you can activate experimental features for Style Kits and Style Kits Pro. We suggest you to turn on backups while using these experiments. %s about how this works.', 'ang' ),
49 | '' . __( 'Learn more', 'ang' ) . ''
50 | ),
51 | 'type' => 'title',
52 | 'id' => 'ang_experiments',
53 | ),
54 | array(
55 | 'title' => __( 'Container-based Library', 'ang' ),
56 | 'desc' => __( 'Get access to the container-based library of Patterns. You need to have the Containers Feature activated in Elementor, to test the new library.', 'ang' ),
57 | 'id' => 'container_library_experiment',
58 | 'default' => 'default',
59 | 'type' => 'select',
60 | 'options' => $options,
61 | ),
62 | array(
63 | 'type' => 'sectionend',
64 | 'id' => 'ang_beta',
65 | ),
66 | )
67 | );
68 |
69 | return apply_filters( 'ang_get_settings_' . $this->id, $settings );
70 | }
71 |
72 | /**
73 | * Output the settings.
74 | */
75 | public function output() {
76 | $settings = $this->get_settings();
77 |
78 | Admin_Settings::output_fields( $settings );
79 | }
80 |
81 | /**
82 | * Save settings.
83 | */
84 | public function save() {
85 | $settings = $this->get_settings();
86 |
87 | Admin_Settings::save_fields( $settings );
88 | }
89 | }
90 |
91 | return new Experiments();
92 |
--------------------------------------------------------------------------------
/inc/settings/class-settings-extensions.php:
--------------------------------------------------------------------------------
1 | id = 'extensions';
25 | $this->label = __( 'Extensions', 'ang' );
26 |
27 | parent::__construct();
28 | }
29 |
30 | /**
31 | * Get sections.
32 | *
33 | * @return array
34 | */
35 | public function get_sections() {
36 | return apply_filters( 'ang_get_sections_' . $this->id, array() );
37 | }
38 |
39 | /**
40 | * Get settings array.
41 | *
42 | * @param string $current_section Current section id.
43 | * @return array
44 | */
45 | public function get_settings( $current_section = '' ) {
46 | global $current_section;
47 | $sections = $this->get_sections();
48 |
49 | if ( ! empty( $sections ) && empty( $current_section ) ) {
50 | $current_section = array_keys( $sections )[0];
51 | }
52 |
53 | $settings = array();
54 | if ( '' === $current_section ) {
55 | $settings = apply_filters(
56 | 'ang_general_extension_settings',
57 | array()
58 | );
59 | }
60 |
61 | return apply_filters( 'ang_get_settings_extensions', $settings, $current_section );
62 | }
63 |
64 | /**
65 | * Output the settings.
66 | */
67 | public function output() {
68 | global $current_section;
69 |
70 | $settings = $this->get_settings( $current_section );
71 |
72 | Admin_Settings::output_fields( $settings );
73 | }
74 |
75 | /**
76 | * Save settings.
77 | */
78 | public function save() {
79 | global $current_section;
80 |
81 | $settings = $this->get_settings( $current_section );
82 |
83 | Admin_Settings::save_fields( $settings );
84 | if ( $current_section ) {
85 | do_action( 'ang_update_options_' . $this->id . '_' . $current_section );
86 | }
87 | }
88 | }
89 |
90 | return new Extensions();
91 |
--------------------------------------------------------------------------------
/inc/settings/class-settings-gopro.php:
--------------------------------------------------------------------------------
1 | id = 'gopro';
27 | $this->label = __( 'Style Kits Pro', 'ang' );
28 | parent::__construct();
29 |
30 | add_action( 'ang_settings_' . $this->id, array( $this, 'get_pro' ) );
31 | }
32 |
33 | /**
34 | * Get settings array.
35 | *
36 | * @return array
37 | */
38 | public function get_settings() {
39 | $settings = apply_filters(
40 | 'ang_gopro_settings',
41 | array()
42 | );
43 |
44 | return apply_filters( 'ang_get_settings_' . $this->id, $settings );
45 | }
46 |
47 | /**
48 | * Get Pro Tab Data.
49 | */
50 | public function get_pro() {
51 | include dirname( __FILE__ ) . '/views/html-admin-settings-gopro.php';
52 | }
53 |
54 | /**
55 | * Output the settings.
56 | */
57 | public function output() {
58 | $settings = $this->get_settings();
59 |
60 | Admin_Settings::output_fields( $settings );
61 | }
62 |
63 | /**
64 | * Save settings.
65 | */
66 | public function save() {
67 | $settings = $this->get_settings();
68 |
69 | Admin_Settings::save_fields( $settings );
70 | }
71 | }
72 |
73 | return new GoPro();
74 |
--------------------------------------------------------------------------------
/inc/settings/views/html-admin-settings-gopro.php:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
Excited with the free version of Style Kits? Try out Style Kits PRO and optimise your Elementor design workflow with more features:
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "analogwp-templates",
3 | "version": "2.3.4",
4 | "description": "Handfully crafted Elementor templates packs.",
5 | "main": "/client/index.js",
6 | "private": true,
7 | "scripts": {
8 | "install-scripts": "composer install && npm install",
9 | "build-app": "wp-scripts build --webpack-src-dir=client --output-path=assets/js/app",
10 | "dev-app": "wp-scripts start --webpack-src-dir=client --output-path=assets/js/app",
11 | "makePot": "wp i18n make-pot . ./languages/ang.pot",
12 | "convertPot2json": "npx po2json ./languages/ang.pot ./languages/ang-analogwp-app.json -f jed1.x",
13 | "build": "gulp build",
14 | "gh:release": "gulp github-build"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/analogwp/analogwp-templates.git"
19 | },
20 | "author": "AnalogWP",
21 | "license": "GPL",
22 | "bugs": {
23 | "url": "https://github.com/analogwp/analogwp-templates/issues"
24 | },
25 | "homepage": "https://github.com/analogwp/analogwp-templates#readme",
26 | "dependencies": {
27 | "classnames": "^2.2.6",
28 | "react-masonry-css": "^1.0.14",
29 | "react-select": "^5.8.2",
30 | "react-waypoint": "^10.3.0",
31 | "regenerator-runtime": "^0.14.1",
32 | "styled-components": "^4.1.3"
33 | },
34 | "devDependencies": {
35 | "@babel/plugin-proposal-class-properties": "^7.5.5",
36 | "@babel/preset-env": "^7.6.3",
37 | "@babel/preset-react": "^7.6.3",
38 | "@wordpress/scripts": "^30.4.0",
39 | "babel-core": "^6.26.3",
40 | "babel-eslint": "^10.0.3",
41 | "babel-loader": "^8.0.6",
42 | "del": "^5.1.0",
43 | "gulp": "^5.0.0",
44 | "gulp-babel": "8.0.0",
45 | "gulp-checktextdomain": "^2.3.0",
46 | "gulp-copy": "^4.0.1",
47 | "gulp-rename": "^1.4.0",
48 | "gulp-rsync": "^0.0.8",
49 | "gulp-run-command": "^0.0.10",
50 | "gulp-uglify": "^3.0.2",
51 | "gulp-zip": "^5.0.1"
52 | },
53 | "files": [
54 | "assets",
55 | "inc",
56 | "languages",
57 | "third-party",
58 | "analogwp-templates.php",
59 | "uninstall.php",
60 | "readme.txt"
61 | ]
62 | }
63 |
--------------------------------------------------------------------------------
/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | A custom set of code standard rules to check for AnalogWP Templates.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | tests/*
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | .
38 |
39 |
40 | /node_modules/*
41 | /build/*
42 | /languages/*
43 |
44 |
--------------------------------------------------------------------------------
/scoper.inc.php:
--------------------------------------------------------------------------------
1 | 'Analog\\Dependencies',
13 | 'finders' => array(
14 | // Enshrined/SVG-Sanitize.
15 | Finder::create()
16 | ->files()
17 | ->ignoreVCS( true )
18 | ->ignoreDotFiles( true )
19 | ->name( '*.php' )
20 | ->exclude(
21 | array(
22 | 'tests',
23 | )
24 | )
25 | ->in( 'vendor/enshrined/svg-sanitize' )
26 | ->append( [ 'vendor/enshrined/svg-sanitize/composer.json' ] ),
27 | Finder::create()->append([
28 | 'composer.json',
29 | ]),
30 | ),
31 | 'patchers' => array(
32 | static function ( string $filePath, string $prefix, string $contents ): string {
33 | // Change the contents here.
34 |
35 | return $contents;
36 | },
37 | ),
38 |
39 | 'exclude-classes' => $wp_classes,
40 | 'exclude-functions' => $wp_functions,
41 | 'exclude-constants' => $wp_constants,
42 | ];
43 |
--------------------------------------------------------------------------------
/tests/_data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/tests/_data/.gitkeep
--------------------------------------------------------------------------------
/tests/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/tests/_support/AcceptanceTester.php:
--------------------------------------------------------------------------------
1 | loginAsAdmin();
8 | }
9 |
10 | private function shouldSaveSettings(AcceptanceTester $I) {
11 | // Ensure settings can be saved.
12 | $I->amOnAdminPage( 'admin.php?page=ang-settings' );
13 |
14 | $I->amGoingTo( 'save page settings without any changes' );
15 | $I->click( 'Save changes' );
16 | $I->see( 'Your settings have been saved.' );
17 |
18 | // Ensure tab click is working fine.
19 | $I->click( 'Misc', '.nav-tab-wrapper' );
20 | $I->see( 'Save changes' );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/acceptance/StyleKitExportImportCest.php:
--------------------------------------------------------------------------------
1 | loginAsAdmin();
8 | }
9 |
10 | public function exportStyleKit( AcceptanceTester $I ) {
11 | $I->amOnAdminPage( 'edit.php?post_type=ang_tokens' );
12 | $I->moveMouseOver( '.column-title.has-row-actions' );
13 | $I->see( 'Export Style Kit' );
14 | $I->click( 'Export Style Kit' );
15 |
16 | $I->wait(3);
17 |
18 | $link = $I->grabAttributeFrom( '.export-template a', 'href' );
19 | $url = parse_url( $link );
20 | parse_str( $url['query'], $params );
21 | $kit_id = $params['kit_id'];
22 |
23 | $name = 'analog-' . $kit_id . '-' . date( 'Y-m-d' ) . '.json';
24 | $I->seeFileFound( $name, $_ENV['DOWNLOAD_LOCATION'] );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/api.suite.yml:
--------------------------------------------------------------------------------
1 | actor: ApiTester
2 | modules:
3 | enabled:
4 | - REST:
5 | url: '%WP_URL%/wp-json/agwp/v1'
6 | depends: PhpBrowser
7 | part: Json
8 | - \Helper\Api
9 |
--------------------------------------------------------------------------------
/tests/api/CheckEndpointsCest.php:
--------------------------------------------------------------------------------
1 | sendGET( 'https://analogwp.com/wp-json/analogwp/v1/info' );
8 | $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
9 | $I->seeResponseIsJson();
10 | $I->seeResponseMatchesJsonType([
11 | 'timestamp' => 'integer',
12 | 'library' => 'array'
13 | ]);
14 |
15 | // Test Blocks.
16 | $I->seeResponseMatchesJsonType(
17 | [
18 | 'id' => 'integer:>0',
19 | 'siteID' => 'integer',
20 | 'title' => 'string',
21 | 'thumbnail' => 'string:url',
22 | 'published' => 'integer',
23 | 'tags' => 'array',
24 | 'popularityIndex' => 'integer',
25 | 'is_pro' => 'boolean',
26 | 'requiredVersion' => 'string|null'
27 | ],
28 | '$.library.blocks[0]'
29 | );
30 |
31 | // Test StyleKits.
32 | $I->seeResponseMatchesJsonType(
33 | [
34 | 'id' => 'integer:>0',
35 | 'title' => 'string',
36 | 'slug' => 'string',
37 | 'image' => 'string:url',
38 | 'site_id' => 'integer',
39 | 'is_pro' => 'boolean',
40 | ],
41 | '$.library.stylekits[0]'
42 | );
43 |
44 | // Test Templates.
45 | $I->seeResponseMatchesJsonType(
46 | [
47 | 'id' => 'string',
48 | 'site_id' => 'string',
49 | 'title' => 'string',
50 | 'thumbnail' => 'string:url',
51 | 'published' => 'integer',
52 | 'url' => 'string:url',
53 | 'type' => 'string',
54 | 'tags' => 'array',
55 | 'page_template' => 'string',
56 | 'popularityIndex' => 'integer',
57 | 'is_pro' => 'boolean',
58 | 'version' => 'string|null',
59 | ],
60 | '$.library.templates[0]'
61 | );
62 |
63 | // Test template_kits.
64 | $I->seeResponseMatchesJsonType(
65 | [
66 | 'title' => 'string',
67 | 'site_id' => 'integer',
68 | 'thumbnail' => 'string:url',
69 | ],
70 | '$.library.template_kits[0]'
71 | );
72 | }
73 |
74 | public function shouldBeUnauthorized( ApiTester $I ) {
75 | $I->sendGET( '/templates' );
76 | $I->seeResponseCodeIs( 401 );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/functional.suite.yml:
--------------------------------------------------------------------------------
1 | # Codeception Test Suite Configuration
2 | #
3 | # Suite for functional tests
4 | # Emulate web requests and make WordPress process them
5 |
6 | actor: FunctionalTester
7 | modules:
8 | enabled:
9 | - WPDb
10 | - WPBrowser
11 | # - WPFilesystem
12 | - Asserts
13 | - \Helper\Functional
14 | config:
15 | WPDb:
16 | dsn: 'mysql:host=%DB_HOST%;dbname=%DB_NAME%'
17 | user: '%DB_USER%'
18 | password: '%DB_PASSWORD%'
19 | dump: 'tests/_data/dump.sql'
20 | populate: true
21 | cleanup: true
22 | waitlock: 0
23 | url: '%WP_URL%'
24 | urlReplacement: true
25 | tablePrefix: '%TABLE_PREFIX%'
26 | WPBrowser:
27 | url: '%WP_URL%'
28 | adminUsername: '%ADMIN_USERNAME%'
29 | adminPassword: '%ADMIN_PASSWORD%'
30 | adminPath: '%WP_ADMIN_PATH%'
31 | WPFilesystem:
32 | wpRootFolder: '%WP_ROOT_FOLDER%'
33 | plugins: '/wp-content/plugins'
34 | mu-plugins: '/wp-content/mu-plugins'
35 | themes: '/wp-content/themes'
36 | uploads: '/wp-content/uploads'
--------------------------------------------------------------------------------
/tests/unit.suite.yml:
--------------------------------------------------------------------------------
1 | # Codeception Test Suite Configuration
2 | #
3 | # Suite for unit or integration tests.
4 |
5 | actor: UnitTester
6 | modules:
7 | enabled:
8 | - Asserts
9 | - \Helper\Unit
--------------------------------------------------------------------------------
/tests/wpunit.suite.yml:
--------------------------------------------------------------------------------
1 | # Codeception Test Suite Configuration
2 | #
3 | # Suite for unit or integration tests that require WordPress functions and classes.
4 |
5 | actor: WpunitTester
6 | modules:
7 | enabled:
8 | - WPLoader
9 | - \Helper\Wpunit
10 | config:
11 | WPLoader:
12 | wpRootFolder: "%WP_ROOT_FOLDER%"
13 | dbName: "%TEST_DB_NAME%"
14 | dbHost: "%TEST_DB_HOST%"
15 | dbUser: "%TEST_DB_USER%"
16 | dbPassword: "%TEST_DB_PASSWORD%"
17 | tablePrefix: "%TEST_TABLE_PREFIX%"
18 | domain: "%WP_DOMAIN%"
19 | adminEmail: "%ADMIN_EMAIL%"
20 | title: "Test"
21 | plugins: ['analogwp-templates/analogwp-templates.php']
22 | activatePlugins: ['analogwp-templates/analogwp-templates.php']
--------------------------------------------------------------------------------
/third-party/composer.json:
--------------------------------------------------------------------------------
1 | { "autoload": { "classmap": [""] } }
2 |
--------------------------------------------------------------------------------
/third-party/vendor/autoload.php:
--------------------------------------------------------------------------------
1 | $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Resolver.php',
10 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Subject' => $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Subject.php',
11 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Usage' => $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Usage.php',
12 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Exceptions\\NestingException' => $vendorDir . '/enshrined/svg-sanitize/src/Exceptions/NestingException.php',
13 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Helper' => $vendorDir . '/enshrined/svg-sanitize/src/Helper.php',
14 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Sanitizer' => $vendorDir . '/enshrined/svg-sanitize/src/Sanitizer.php',
15 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedAttributes' => $vendorDir . '/enshrined/svg-sanitize/src/data/AllowedAttributes.php',
16 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedTags' => $vendorDir . '/enshrined/svg-sanitize/src/data/AllowedTags.php',
17 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AttributeInterface' => $vendorDir . '/enshrined/svg-sanitize/src/data/AttributeInterface.php',
18 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\TagInterface' => $vendorDir . '/enshrined/svg-sanitize/src/data/TagInterface.php',
19 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\XPath' => $vendorDir . '/enshrined/svg-sanitize/src/data/XPath.php',
20 | 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
21 | );
22 |
--------------------------------------------------------------------------------
/third-party/vendor/composer/autoload_namespaces.php:
--------------------------------------------------------------------------------
1 | setClassMapAuthoritative(true);
33 | $loader->register(true);
34 |
35 | return $loader;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/third-party/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 | __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Resolver.php',
11 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Subject' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Subject.php',
12 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Usage' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Usage.php',
13 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Exceptions\\NestingException' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Exceptions/NestingException.php',
14 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Helper' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Helper.php',
15 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Sanitizer' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Sanitizer.php',
16 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedAttributes' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AllowedAttributes.php',
17 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedTags' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AllowedTags.php',
18 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AttributeInterface' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AttributeInterface.php',
19 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\TagInterface' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/TagInterface.php',
20 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\XPath' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/XPath.php',
21 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
22 | );
23 |
24 | public static function getInitializer(ClassLoader $loader)
25 | {
26 | return \Closure::bind(function () use ($loader) {
27 | $loader->classMap = ComposerStaticInitf898fd6c5f659794d92b538c45d56a06::$classMap;
28 |
29 | }, null, ClassLoader::class);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/third-party/vendor/enshrined/svg-sanitize/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "enshrined\/svg-sanitize",
3 | "description": "An SVG sanitizer for PHP",
4 | "license": "GPL-2.0-or-later",
5 | "authors": [
6 | {
7 | "name": "Daryll Doyle",
8 | "email": "daryll@enshrined.co.uk"
9 | }
10 | ],
11 | "scripts": {
12 | "test": "phpunit --no-coverage",
13 | "test:coverage": "phpunit"
14 | },
15 | "autoload": {
16 | "psr-4": {
17 | "Analog\\Dependencies\\enshrined\\svgSanitize\\": "src"
18 | }
19 | },
20 | "autoload-dev": {
21 | "psr-4": {
22 | "Analog\\Dependencies\\enshrined\\svgSanitize\\Tests\\": "tests"
23 | }
24 | },
25 | "require": {
26 | "ext-dom": "*",
27 | "ext-libxml": "*",
28 | "php": "^7.0 || ^8.0"
29 | },
30 | "require-dev": {
31 | "phpunit\/phpunit": "^6.5 || ^8.5"
32 | }
33 | }
--------------------------------------------------------------------------------
/third-party/vendor/enshrined/svg-sanitize/src/ElementReference/Usage.php:
--------------------------------------------------------------------------------
1 | subject = $subject;
22 | $this->count = (int) $count;
23 | }
24 | /**
25 | * @param int $by
26 | */
27 | public function increment($by = 1)
28 | {
29 | $this->count += (int) $by;
30 | }
31 | /**
32 | * @return Subject
33 | */
34 | public function getSubject()
35 | {
36 | return $this->subject;
37 | }
38 | /**
39 | * @return int
40 | */
41 | public function getCount()
42 | {
43 | return $this->count;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/third-party/vendor/enshrined/svg-sanitize/src/Exceptions/NestingException.php:
--------------------------------------------------------------------------------
1 | element = $element;
23 | parent::__construct($message, $code, $previous);
24 | }
25 | /**
26 | * Get the element that caused the exception.
27 | *
28 | * @return \DOMElement
29 | */
30 | public function getElement()
31 | {
32 | return $this->element;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/third-party/vendor/enshrined/svg-sanitize/src/Helper.php:
--------------------------------------------------------------------------------
1 | hasAttribute('href')) {
14 | return $element->getAttribute('href');
15 | }
16 | if ($element->hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
17 | return $element->getAttributeNS('http://www.w3.org/1999/xlink', 'href');
18 | }
19 | return null;
20 | }
21 | /**
22 | * @param string $href
23 | * @return string|null
24 | */
25 | public static function extractIdReferenceFromHref($href)
26 | {
27 | if (!\is_string($href) || \strpos($href, '#') !== 0) {
28 | return null;
29 | }
30 | return \substr($href, 1);
31 | }
32 | /**
33 | * @param \DOMElement $needle
34 | * @param \DOMElement $haystack
35 | * @return bool
36 | */
37 | public static function isElementContainedIn(\DOMElement $needle, \DOMElement $haystack)
38 | {
39 | if ($needle === $haystack) {
40 | return \true;
41 | }
42 | foreach ($haystack->childNodes as $childNode) {
43 | if (!$childNode instanceof \DOMElement) {
44 | continue;
45 | }
46 | if (self::isElementContainedIn($needle, $childNode)) {
47 | return \true;
48 | }
49 | }
50 | return \false;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/third-party/vendor/enshrined/svg-sanitize/src/data/AttributeInterface.php:
--------------------------------------------------------------------------------
1 | handleDefaultNamespace();
16 | }
17 | /**
18 | * @param string $nodeName
19 | * @return string
20 | */
21 | public function createNodeName($nodeName)
22 | {
23 | if (empty($this->defaultNamespaceURI)) {
24 | return $nodeName;
25 | }
26 | return self::DEFAULT_NAMESPACE_PREFIX . ':' . $nodeName;
27 | }
28 | protected function handleDefaultNamespace()
29 | {
30 | $rootElements = $this->getRootElements();
31 | if (\count($rootElements) !== 1) {
32 | throw new \LogicException(\sprintf('Got %d svg elements, expected exactly one', \count($rootElements)), 1570870568);
33 | }
34 | $this->defaultNamespaceURI = (string) $rootElements[0]->namespaceURI;
35 | if ($this->defaultNamespaceURI !== '') {
36 | $this->registerNamespace(self::DEFAULT_NAMESPACE_PREFIX, $this->defaultNamespaceURI);
37 | }
38 | }
39 | /**
40 | * @return \DOMElement[]
41 | */
42 | protected function getRootElements()
43 | {
44 | $rootElements = [];
45 | $elements = $this->document->getElementsByTagName('svg');
46 | /** @var \DOMElement $element */
47 | foreach ($elements as $element) {
48 | if ($element->parentNode !== $this->document) {
49 | continue;
50 | }
51 | $rootElements[] = $element;
52 | }
53 | return $rootElements;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/third-party/vendor/scoper-autoload.php:
--------------------------------------------------------------------------------
1 | files_manager->clear_cache();
31 | }
32 |
--------------------------------------------------------------------------------