Full Code of gocodebox/lifterlms for AI

trunk 8c7f47418740 cached
1659 files
9.4 MB
2.6M tokens
7986 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (10,210K chars total). Download the full file to get everything.
Repository: gocodebox/lifterlms
Branch: trunk
Commit: 8c7f47418740
Files: 1659
Total size: 9.4 MB

Directory structure:
gitextract_4knxr8ph/

├── .codeclimate.yml
├── .cursor/
│   └── BUGBOT.md
├── .editorconfig
├── .eslintrc.js
├── .github/
│   ├── CODEOWNERS
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── Bug_Report.md
│   │   ├── Feature_Request.md
│   │   └── Question.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── SECURITY.md
│   ├── workflow-matrix.yml
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── contributors.yml
│       ├── keep-alive.yml
│       ├── lint-js.yml
│       ├── ossar-analysis.yml
│       ├── project-automation.yml
│       ├── publish.yml
│       ├── sync-branches.yml
│       ├── test-e2e.yml
│       ├── test-js-unit.yml
│       └── test-phpunit.yml
├── .gitignore
├── .llmsconfig
├── .llmsdev.yml
├── .llmsdevrc
├── .llmsenv.dist
├── .source/
│   └── README.md
├── .wordpress-org/
│   ├── README.md
│   └── readme/
│       ├── 01-header.md
│       ├── 05-description.md
│       ├── 10-installation.md
│       ├── 15-faqs.md
│       ├── 20-screenshots.md
│       └── 25-changelog.md
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets/
│   ├── css/
│   │   ├── bricks-editor.css
│   │   ├── dancing-script.css
│   │   ├── imperial-script.css
│   │   ├── pirata-one.css
│   │   └── unifraktur-maguntia.css
│   ├── fonts/
│   │   └── FontAwesome.otf
│   ├── js/
│   │   ├── app/
│   │   │   ├── llms-achievements.js
│   │   │   ├── llms-ajax.js
│   │   │   ├── llms-donut.js
│   │   │   ├── llms-forms.js
│   │   │   ├── llms-instructors.js
│   │   │   ├── llms-l10n.js
│   │   │   ├── llms-lesson-preview.js
│   │   │   ├── llms-outline-collapse.js
│   │   │   ├── llms-password-strength.js
│   │   │   ├── llms-pricing-tables.js
│   │   │   ├── llms-quiz-attempt.js
│   │   │   ├── llms-review.js
│   │   │   ├── llms-storage.js
│   │   │   ├── llms-student-dashboard.js
│   │   │   ├── llms-tracking.js
│   │   │   ├── llms-visibility-toggle.js
│   │   │   └── rest.js
│   │   ├── builder/
│   │   │   ├── Collections/
│   │   │   │   ├── Lessons.js
│   │   │   │   ├── QuestionChoices.js
│   │   │   │   ├── QuestionTypes.js
│   │   │   │   ├── Questions.js
│   │   │   │   ├── Sections.js
│   │   │   │   └── loader.js
│   │   │   ├── Controllers/
│   │   │   │   ├── Construct.js
│   │   │   │   ├── Debug.js
│   │   │   │   ├── Schemas.js
│   │   │   │   └── Sync.js
│   │   │   ├── Models/
│   │   │   │   ├── Abstract.js
│   │   │   │   ├── Course.js
│   │   │   │   ├── Image.js
│   │   │   │   ├── Lesson.js
│   │   │   │   ├── Question.js
│   │   │   │   ├── QuestionChoice.js
│   │   │   │   ├── QuestionType.js
│   │   │   │   ├── Quiz.js
│   │   │   │   ├── Section.js
│   │   │   │   ├── _Relationships.js
│   │   │   │   ├── _Utilities.js
│   │   │   │   └── loader.js
│   │   │   ├── Schemas/
│   │   │   │   ├── Lesson.js
│   │   │   │   └── Quiz.js
│   │   │   ├── Views/
│   │   │   │   ├── Assignment.js
│   │   │   │   ├── Course.js
│   │   │   │   ├── Editor.js
│   │   │   │   ├── Elements.js
│   │   │   │   ├── FormattingToolbar.js
│   │   │   │   ├── Lesson.js
│   │   │   │   ├── LessonEditor.js
│   │   │   │   ├── LessonList.js
│   │   │   │   ├── Popover.js
│   │   │   │   ├── PostSearch.js
│   │   │   │   ├── Question.js
│   │   │   │   ├── QuestionBank.js
│   │   │   │   ├── QuestionChoice.js
│   │   │   │   ├── QuestionChoiceList.js
│   │   │   │   ├── QuestionList.js
│   │   │   │   ├── QuestionType.js
│   │   │   │   ├── Quiz.js
│   │   │   │   ├── Section.js
│   │   │   │   ├── SectionList.js
│   │   │   │   ├── SettingsFields.js
│   │   │   │   ├── Sidebar.js
│   │   │   │   ├── Utilities.js
│   │   │   │   ├── _Detachable.js
│   │   │   │   ├── _Editable.js
│   │   │   │   ├── _Receivable.js
│   │   │   │   ├── _Shiftable.js
│   │   │   │   ├── _Subview.js
│   │   │   │   ├── _Trashable.js
│   │   │   │   └── _loader.js
│   │   │   ├── backbone.js
│   │   │   ├── jquery.js
│   │   │   ├── main.js
│   │   │   ├── underscore.js
│   │   │   └── vendor/
│   │   │       ├── almond.js
│   │   │       ├── backbone.collectionView.js
│   │   │       ├── backbone.trackit.js
│   │   │       └── wp-hooks.js
│   │   ├── llms-admin-forms.js
│   │   ├── llms-admin-media-protection-attachment-settings.js
│   │   ├── llms-admin-settings.js
│   │   ├── llms-admin-tables.js
│   │   ├── llms-admin-wizard.js
│   │   ├── llms-admin.js
│   │   ├── llms-ajax.js
│   │   ├── llms-analytics.js
│   │   ├── llms-favorites.js
│   │   ├── llms-focus-mode.js
│   │   ├── llms-form-checkout.js
│   │   ├── llms-launch-course-button.js
│   │   ├── llms-metabox-achievement.js
│   │   ├── llms-metabox-certificate.js
│   │   ├── llms-metabox-fields.js
│   │   ├── llms-metabox-instructors.js
│   │   ├── llms-metabox-options.js
│   │   ├── llms-metabox-product.js
│   │   ├── llms-metabox-students.js
│   │   ├── llms-metabox-voucher.js
│   │   ├── llms-notifications.js
│   │   ├── llms-quiz-attempt-review.js
│   │   ├── llms-quiz.js
│   │   ├── llms-view-manager.js
│   │   ├── llms-widget-syllabus.js
│   │   ├── partials/
│   │   │   └── _metabox-field-repeater.js
│   │   ├── private/
│   │   │   ├── llms-metaboxes.js
│   │   │   └── llms.js
│   │   └── vendor/
│   │       ├── jquery.matchHeight.js
│   │       └── js.cookie.js
│   ├── scss/
│   │   ├── _includes/
│   │   │   ├── _buttons.scss
│   │   │   ├── _extends.scss
│   │   │   ├── _grid.scss
│   │   │   ├── _llms-donut.scss
│   │   │   ├── _llms-form-field.scss
│   │   │   ├── _mixins.scss
│   │   │   ├── _quiz-result-question-list.scss
│   │   │   ├── _tooltip.scss
│   │   │   ├── _vars-brand-colors.scss
│   │   │   ├── _vars.scss
│   │   │   └── vendor/
│   │   │       └── _font-awesome.scss
│   │   ├── admin/
│   │   │   ├── _course-builder.scss
│   │   │   ├── _dashboard-widget.scss
│   │   │   ├── _dashboard.scss
│   │   │   ├── _fonts.scss
│   │   │   ├── _llms-table.scss
│   │   │   ├── _main.scss
│   │   │   ├── _media-protection.scss
│   │   │   ├── _quiz-attempt-review.scss
│   │   │   ├── _reporting.scss
│   │   │   ├── _resources.scss
│   │   │   ├── _settings.scss
│   │   │   ├── _tabs.scss
│   │   │   ├── _wp-menu.scss
│   │   │   ├── breakpoints/
│   │   │   │   ├── _1030up.scss
│   │   │   │   ├── _1240up.scss
│   │   │   │   ├── _481up.scss
│   │   │   │   ├── _768up.scss
│   │   │   │   └── _base.scss
│   │   │   ├── metaboxes/
│   │   │   │   ├── _builder-launcher.scss
│   │   │   │   ├── _llms-metabox.scss
│   │   │   │   ├── _metabox-engagements-type.scss
│   │   │   │   ├── _metabox-field-repeater.scss
│   │   │   │   ├── _metabox-instructors.scss
│   │   │   │   ├── _metabox-orders.scss
│   │   │   │   ├── _metabox-product.scss
│   │   │   │   └── _metabox-students.scss
│   │   │   ├── modules/
│   │   │   │   ├── _forms.scss
│   │   │   │   ├── _icons.scss
│   │   │   │   ├── _llms-order-note.scss
│   │   │   │   ├── _mb-tabs.scss
│   │   │   │   ├── _merge-codes.scss
│   │   │   │   ├── _top-modal.scss
│   │   │   │   ├── _voucher.scss
│   │   │   │   └── _widgets.scss
│   │   │   ├── partials/
│   │   │   │   └── _grid.scss
│   │   │   └── post-tables/
│   │   │       ├── _llms_orders.scss
│   │   │       └── _post-tables.scss
│   │   ├── admin-importer.scss
│   │   ├── admin-wizard.scss
│   │   ├── admin.scss
│   │   ├── builder.scss
│   │   ├── certificates.scss
│   │   ├── editor.scss
│   │   ├── frontend/
│   │   │   ├── _checkout.scss
│   │   │   ├── _course.scss
│   │   │   ├── _focus-mode.scss
│   │   │   ├── _llms-access-plans.scss
│   │   │   ├── _llms-achievements-certs.scss
│   │   │   ├── _llms-author.scss
│   │   │   ├── _llms-notifications.scss
│   │   │   ├── _llms-outline-collapse.scss
│   │   │   ├── _llms-pagination.scss
│   │   │   ├── _llms-progress.scss
│   │   │   ├── _llms-quizzes.scss
│   │   │   ├── _llms-table.scss
│   │   │   ├── _loop.scss
│   │   │   ├── _main.scss
│   │   │   ├── _notices.scss
│   │   │   ├── _reviews.scss
│   │   │   ├── _student-dashboard.scss
│   │   │   ├── _syllabus.scss
│   │   │   ├── _tooltip.scss
│   │   │   └── _voucher.scss
│   │   ├── lifterlms.scss
│   │   └── llms-focus-mode.scss
│   └── vendor/
│       ├── a11y-dialog/
│       │   └── LICENSE
│       ├── datetimepicker/
│       │   └── jquery.datetimepicker.full.js
│       ├── izimodal/
│       │   ├── iziModal.css
│       │   └── iziModal.js
│       ├── jquery-ui-flick/
│       │   └── jquery-ui-flick.css
│       ├── quill/
│       │   ├── quill.bubble.css
│       │   ├── quill.js
│       │   ├── quill.js.LICENSE.txt
│       │   └── quill.module.wordcount.js
│       ├── select2/
│       │   ├── css/
│       │   │   └── select2.css
│       │   └── js/
│       │       └── select2.js
│       └── webui-popover/
│           ├── jquery.webui-popover.css
│           └── jquery.webui-popover.js
├── babel.config.js
├── class-lifterlms.php
├── composer.json
├── docker-compose.yml
├── docs/
│   ├── block-development.md
│   ├── coding-standards.md
│   ├── contributing.md
│   ├── documentation-standards.md
│   ├── e2e-tests-real.md
│   └── installing.md
├── gulpfile.js/
│   ├── index.js
│   └── tasks/
│       ├── hacky-clean.js
│       ├── js-additional.js
│       └── js-builder.js
├── includes/
│   ├── abstracts/
│   │   ├── abstract.llms.admin.metabox.php
│   │   ├── abstract.llms.admin.table.php
│   │   ├── abstract.llms.analytics.widget.php
│   │   ├── abstract.llms.database.query.php
│   │   ├── abstract.llms.payment.gateway.php
│   │   ├── abstract.llms.post.model.php
│   │   ├── abstract.llms.shortcode.course.element.php
│   │   ├── abstract.llms.shortcode.php
│   │   ├── abstract.llms.update.php
│   │   ├── index.php
│   │   ├── llms-abstract-admin-tool.php
│   │   ├── llms-abstract-admin-wizard.php
│   │   ├── llms-abstract-controller-user-engagements.php
│   │   ├── llms-abstract-email-provider.php
│   │   ├── llms-abstract-generator-posts.php
│   │   ├── llms-abstract-meta-box-user-engagement-sync.php
│   │   ├── llms-abstract-posts-query.php
│   │   ├── llms-abstract-processor-user-engagement-sync.php
│   │   ├── llms-abstract-query.php
│   │   ├── llms-abstract-session-data.php
│   │   ├── llms-abstract-session-database-handler.php
│   │   ├── llms-abstract-user-engagement.php
│   │   ├── llms.abstract.api.handler.php
│   │   ├── llms.abstract.database.store.php
│   │   ├── llms.abstract.exportable.admin.table.php
│   │   ├── llms.abstract.integration.php
│   │   ├── llms.abstract.notification.controller.php
│   │   ├── llms.abstract.notification.processor.php
│   │   ├── llms.abstract.notification.view.php
│   │   ├── llms.abstract.notification.view.quiz.completion.php
│   │   ├── llms.abstract.options.data.php
│   │   ├── llms.abstract.post.data.php
│   │   ├── llms.abstract.privacy.php
│   │   ├── llms.abstract.processor.php
│   │   └── llms.abstract.user.data.php
│   ├── achievements/
│   │   ├── class.llms.achievement.user.php
│   │   └── index.php
│   ├── admin/
│   │   ├── class-llms-admin-events-promo.php
│   │   ├── class-llms-admin-export-download.php
│   │   ├── class-llms-admin-header.php
│   │   ├── class-llms-admin-media-protection-attachment-settings.php
│   │   ├── class-llms-admin-permalinks.php
│   │   ├── class-llms-admin-plugins.php
│   │   ├── class-llms-admin-profile.php
│   │   ├── class-llms-admin-review.php
│   │   ├── class-llms-admin-users-table.php
│   │   ├── class-llms-export-api.php
│   │   ├── class-llms-mailhawk.php
│   │   ├── class-llms-sendwp.php
│   │   ├── class.llms.admin.addons.php
│   │   ├── class.llms.admin.assets.php
│   │   ├── class.llms.admin.builder.php
│   │   ├── class.llms.admin.dashboard-widget.php
│   │   ├── class.llms.admin.dashboard.php
│   │   ├── class.llms.admin.import.php
│   │   ├── class.llms.admin.menus.php
│   │   ├── class.llms.admin.notices.core.php
│   │   ├── class.llms.admin.notices.php
│   │   ├── class.llms.admin.page.status.php
│   │   ├── class.llms.admin.post-types.php
│   │   ├── class.llms.admin.resources.php
│   │   ├── class.llms.admin.reviews.php
│   │   ├── class.llms.admin.settings.php
│   │   ├── class.llms.admin.setup.wizard.php
│   │   ├── class.llms.admin.system-report.php
│   │   ├── class.llms.admin.user.custom.fields.php
│   │   ├── class.llms.student.bulk.enroll.php
│   │   ├── index.php
│   │   ├── llms.functions.admin.php
│   │   ├── post-types/
│   │   │   ├── class.llms.meta.boxes.php
│   │   │   ├── class.llms.post.tables.php
│   │   │   ├── index.php
│   │   │   ├── meta-boxes/
│   │   │   │   ├── class-llms-meta-box-achievement-sync.php
│   │   │   │   ├── class-llms-meta-box-certificate-sync.php
│   │   │   │   ├── class.llms.meta.box.access.php
│   │   │   │   ├── class.llms.meta.box.achievement.php
│   │   │   │   ├── class.llms.meta.box.award.engagement.submit.php
│   │   │   │   ├── class.llms.meta.box.certificate.php
│   │   │   │   ├── class.llms.meta.box.coupon.php
│   │   │   │   ├── class.llms.meta.box.course.builder.php
│   │   │   │   ├── class.llms.meta.box.course.options.php
│   │   │   │   ├── class.llms.meta.box.course.short.description.php
│   │   │   │   ├── class.llms.meta.box.email.settings.php
│   │   │   │   ├── class.llms.meta.box.engagement.php
│   │   │   │   ├── class.llms.meta.box.lesson.php
│   │   │   │   ├── class.llms.meta.box.membership.php
│   │   │   │   ├── class.llms.meta.box.order.details.php
│   │   │   │   ├── class.llms.meta.box.order.enrollment.php
│   │   │   │   ├── class.llms.meta.box.order.notes.php
│   │   │   │   ├── class.llms.meta.box.order.submit.php
│   │   │   │   ├── class.llms.meta.box.order.transactions.php
│   │   │   │   ├── class.llms.meta.box.product.php
│   │   │   │   ├── class.llms.meta.box.students.php
│   │   │   │   ├── class.llms.meta.box.visibility.php
│   │   │   │   ├── class.llms.meta.box.voucher.export.php
│   │   │   │   ├── class.llms.meta.box.voucher.php
│   │   │   │   ├── fields/
│   │   │   │   │   ├── index.php
│   │   │   │   │   ├── llms.class.meta.box.basic.editor.php
│   │   │   │   │   ├── llms.class.meta.box.button.php
│   │   │   │   │   ├── llms.class.meta.box.checkbox.php
│   │   │   │   │   ├── llms.class.meta.box.color.php
│   │   │   │   │   ├── llms.class.meta.box.custom.html.php
│   │   │   │   │   ├── llms.class.meta.box.date.php
│   │   │   │   │   ├── llms.class.meta.box.editor.php
│   │   │   │   │   ├── llms.class.meta.box.fields.php
│   │   │   │   │   ├── llms.class.meta.box.hidden.php
│   │   │   │   │   ├── llms.class.meta.box.image.php
│   │   │   │   │   ├── llms.class.meta.box.number.php
│   │   │   │   │   ├── llms.class.meta.box.post.content.php
│   │   │   │   │   ├── llms.class.meta.box.post.excerpt.php
│   │   │   │   │   ├── llms.class.meta.box.repeater.php
│   │   │   │   │   ├── llms.class.meta.box.search.php
│   │   │   │   │   ├── llms.class.meta.box.select.php
│   │   │   │   │   ├── llms.class.meta.box.table.php
│   │   │   │   │   ├── llms.class.meta.box.text.php
│   │   │   │   │   ├── llms.class.meta.box.textarea.php
│   │   │   │   │   ├── llms.class.meta.box.textarea.tags.php
│   │   │   │   │   └── llms.interface.meta.box.field.php
│   │   │   │   └── index.php
│   │   │   ├── post-tables/
│   │   │   │   ├── class-llms-admin-post-table-achievements.php
│   │   │   │   ├── class-llms-admin-post-table-awards.php
│   │   │   │   ├── class-llms-admin-post-table-certificates.php
│   │   │   │   ├── class-llms-admin-post-table-forms.php
│   │   │   │   ├── class.llms.admin.post.table.coupons.php
│   │   │   │   ├── class.llms.admin.post.table.courses.php
│   │   │   │   ├── class.llms.admin.post.table.engagements.php
│   │   │   │   ├── class.llms.admin.post.table.instructors.php
│   │   │   │   ├── class.llms.admin.post.table.lessons.php
│   │   │   │   ├── class.llms.admin.post.table.orders.php
│   │   │   │   ├── class.llms.admin.post.table.pages.php
│   │   │   │   └── index.php
│   │   │   └── tables/
│   │   │       ├── class.llms.table.student.management.php
│   │   │       └── index.php
│   │   ├── reporting/
│   │   │   ├── class.llms.admin.reporting.php
│   │   │   ├── index.php
│   │   │   ├── tables/
│   │   │   │   ├── index.php
│   │   │   │   ├── llms.table.achievements.php
│   │   │   │   ├── llms.table.certificates.php
│   │   │   │   ├── llms.table.course.students.php
│   │   │   │   ├── llms.table.courses.php
│   │   │   │   ├── llms.table.membership.students.php
│   │   │   │   ├── llms.table.memberships.php
│   │   │   │   ├── llms.table.quiz.attempts.php
│   │   │   │   ├── llms.table.quiz.non.attempts.php
│   │   │   │   ├── llms.table.quizzes.php
│   │   │   │   ├── llms.table.student.course.php
│   │   │   │   ├── llms.table.student.courses.php
│   │   │   │   ├── llms.table.student.memberships.php
│   │   │   │   ├── llms.table.student.quiz.attempts.php
│   │   │   │   └── llms.table.students.php
│   │   │   ├── tabs/
│   │   │   │   ├── class.llms.admin.reporting.tab.courses.php
│   │   │   │   ├── class.llms.admin.reporting.tab.enrollments.php
│   │   │   │   ├── class.llms.admin.reporting.tab.memberships.php
│   │   │   │   ├── class.llms.admin.reporting.tab.quizzes.php
│   │   │   │   ├── class.llms.admin.reporting.tab.sales.php
│   │   │   │   ├── class.llms.admin.reporting.tab.students.php
│   │   │   │   └── index.php
│   │   │   └── widgets/
│   │   │       ├── class.llms.analytics.widget.ajax.php
│   │   │       ├── class.llms.analytics.widget.coupons.php
│   │   │       ├── class.llms.analytics.widget.coursecompletions.php
│   │   │       ├── class.llms.analytics.widget.discounts.php
│   │   │       ├── class.llms.analytics.widget.enrollments.php
│   │   │       ├── class.llms.analytics.widget.lessoncompletions.php
│   │   │       ├── class.llms.analytics.widget.refunded.php
│   │   │       ├── class.llms.analytics.widget.refunds.php
│   │   │       ├── class.llms.analytics.widget.registrations.php
│   │   │       ├── class.llms.analytics.widget.revenue.php
│   │   │       ├── class.llms.analytics.widget.sales.php
│   │   │       ├── class.llms.analytics.widget.sold.php
│   │   │       ├── class.llms.analytics.widget.transactions.php
│   │   │       └── index.php
│   │   ├── settings/
│   │   │   ├── class.llms.settings.accounts.php
│   │   │   ├── class.llms.settings.checkout.php
│   │   │   ├── class.llms.settings.courses.php
│   │   │   ├── class.llms.settings.engagements.php
│   │   │   ├── class.llms.settings.general.php
│   │   │   ├── class.llms.settings.integrations.php
│   │   │   ├── class.llms.settings.memberships.php
│   │   │   ├── class.llms.settings.notifications.php
│   │   │   ├── class.llms.settings.page.php
│   │   │   ├── class.llms.settings.security.php
│   │   │   ├── index.php
│   │   │   └── tables/
│   │   │       ├── class.llms.table.notification.settings.php
│   │   │       └── index.php
│   │   ├── tools/
│   │   │   ├── class-llms-admin-tool-batch-eraser.php
│   │   │   ├── class-llms-admin-tool-clear-sessions.php
│   │   │   ├── class-llms-admin-tool-course-data-lock-eraser.php
│   │   │   ├── class-llms-admin-tool-install-forms.php
│   │   │   ├── class-llms-admin-tool-limited-billing-order-locator.php
│   │   │   ├── class-llms-admin-tool-recurring-payment-rescheduler.php
│   │   │   ├── class-llms-admin-tool-reset-automatic-payments.php
│   │   │   ├── class-llms-admin-tool-wipe-legacy-account-options.php
│   │   │   └── index.php
│   │   └── views/
│   │       ├── access-plans/
│   │       │   ├── access-plan-dialog.php
│   │       │   ├── access-plan.php
│   │       │   ├── index.php
│   │       │   └── metabox.php
│   │       ├── addons/
│   │       │   ├── addon-item.php
│   │       │   └── index.php
│   │       ├── builder/
│   │       │   ├── assignment.php
│   │       │   ├── course.php
│   │       │   ├── editor.php
│   │       │   ├── elements.php
│   │       │   ├── index.php
│   │       │   ├── lesson-settings.php
│   │       │   ├── lesson.php
│   │       │   ├── question-choice.php
│   │       │   ├── question-type.php
│   │       │   ├── question.php
│   │       │   ├── quiz.php
│   │       │   ├── section.php
│   │       │   ├── settings-fields.php
│   │       │   ├── sidebar.php
│   │       │   └── utilities.php
│   │       ├── dashboard/
│   │       │   ├── addons.php
│   │       │   ├── blog.php
│   │       │   ├── index.php
│   │       │   ├── podcast.php
│   │       │   └── quick-links.php
│   │       ├── dashboard.php
│   │       ├── import/
│   │       │   ├── help-sidebar.php
│   │       │   ├── help-tab-overview.php
│   │       │   └── index.php
│   │       ├── import.php
│   │       ├── importable-course.php
│   │       ├── importable-courses.php
│   │       ├── index.php
│   │       ├── merge-code-button.php
│   │       ├── metaboxes/
│   │       │   ├── index.php
│   │       │   ├── view-award-engagement-submit.php
│   │       │   ├── view-order-details.php
│   │       │   └── view-order-submit.php
│   │       ├── notices/
│   │       │   ├── db-update.php
│   │       │   ├── index.php
│   │       │   └── review-request.php
│   │       ├── reporting/
│   │       │   ├── index.php
│   │       │   └── widget.php
│   │       ├── resources/
│   │       │   ├── getting-started.php
│   │       │   ├── index.php
│   │       │   ├── resource-links.php
│   │       │   └── welcome-video.php
│   │       ├── resources.php
│   │       ├── settings.php
│   │       ├── setup-wizard/
│   │       │   ├── index.php
│   │       │   ├── main.php
│   │       │   ├── step-coupon.php
│   │       │   ├── step-finish.php
│   │       │   ├── step-intro.php
│   │       │   ├── step-pages.php
│   │       │   └── step-payments.php
│   │       ├── status/
│   │       │   ├── index.php
│   │       │   └── view-log.php
│   │       └── user-edit-fields.php
│   ├── assets/
│   │   ├── index.php
│   │   ├── llms-assets-scripts.php
│   │   └── llms-assets-styles.php
│   ├── beaver-builder/
│   │   ├── index.php
│   │   ├── modules/
│   │   │   ├── course-author/
│   │   │   │   ├── class.llms.lab.course.author.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-continue-button/
│   │   │   │   ├── class.llms.lab.course.continue.button.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-instructors/
│   │   │   │   ├── class.llms.lab.course.instructors.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-meta-info/
│   │   │   │   ├── class.llms.lab.course.meta.info.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-progress-bar/
│   │   │   │   ├── class.llms.lab.course.progress.bar.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-syllabus/
│   │   │   │   ├── class.llms.lab.course.syllabus.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── index.php
│   │   │   ├── lesson-mark-complete/
│   │   │   │   ├── class.llms.lab.lesson.mark.complete.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── membership-instructors/
│   │   │   │   ├── class.llms.lab.membership.instructors.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   └── pricing-table/
│   │   │       ├── class.llms.lab.pricing.table.module.php
│   │   │       ├── includes/
│   │   │       │   ├── frontend.php
│   │   │       │   └── index.php
│   │   │       ├── index.php
│   │   │       └── js/
│   │   │           └── frontend.js
│   │   └── templates/
│   │       └── index.php
│   ├── bricks/
│   │   ├── class-llms-bricks-element-course-author.php
│   │   ├── class-llms-bricks-element-course-continue.php
│   │   ├── class-llms-bricks-element-course-information.php
│   │   ├── class-llms-bricks-element-course-meta-info.php
│   │   ├── class-llms-bricks-element-course-progress.php
│   │   ├── class-llms-bricks-element-course-syllabus.php
│   │   ├── class-llms-bricks-element-instructors.php
│   │   ├── class-llms-bricks-element-lesson-progression.php
│   │   └── class-llms-bricks-element-pricing-table.php
│   ├── certificates/
│   │   ├── class.llms.certificate.user.php
│   │   └── index.php
│   ├── class-llms-assets.php
│   ├── class-llms-awards-query.php
│   ├── class-llms-beaver-builder-migrate.php
│   ├── class-llms-beaver-builder.php
│   ├── class-llms-block-library.php
│   ├── class-llms-block-templates.php
│   ├── class-llms-bricks.php
│   ├── class-llms-course-completion-page.php
│   ├── class-llms-db-ugrader.php
│   ├── class-llms-dom-document.php
│   ├── class-llms-elementor-migrate.php
│   ├── class-llms-engagement-handler.php
│   ├── class-llms-events-core.php
│   ├── class-llms-events-query.php
│   ├── class-llms-events.php
│   ├── class-llms-generator-courses.php
│   ├── class-llms-grades.php
│   ├── class-llms-loader.php
│   ├── class-llms-media-protector.php
│   ├── class-llms-mime-type-extractor.php
│   ├── class-llms-order-generator.php
│   ├── class-llms-prevent-concurrent-logins.php
│   ├── class-llms-rest-fields.php
│   ├── class-llms-sessions.php
│   ├── class-llms-staging.php
│   ├── class.llms.achievement.php
│   ├── class.llms.achievements.php
│   ├── class.llms.ajax.handler.php
│   ├── class.llms.ajax.php
│   ├── class.llms.background.updater.php
│   ├── class.llms.cache.helper.php
│   ├── class.llms.certificate.php
│   ├── class.llms.certificates.php
│   ├── class.llms.comments.php
│   ├── class.llms.course.data.php
│   ├── class.llms.data.php
│   ├── class.llms.date.php
│   ├── class.llms.dot.com.api.php
│   ├── class.llms.emails.php
│   ├── class.llms.engagements.php
│   ├── class.llms.frontend.assets.php
│   ├── class.llms.gateway.manual.php
│   ├── class.llms.generator.php
│   ├── class.llms.hasher.php
│   ├── class.llms.https.php
│   ├── class.llms.install.php
│   ├── class.llms.integrations.php
│   ├── class.llms.l10n.php
│   ├── class.llms.lesson.handler.php
│   ├── class.llms.membership.data.php
│   ├── class.llms.nav.menus.php
│   ├── class.llms.oembed.php
│   ├── class.llms.payment.gateways.php
│   ├── class.llms.person.handler.php
│   ├── class.llms.playnice.php
│   ├── class.llms.post-types.php
│   ├── class.llms.post.handler.php
│   ├── class.llms.post.relationships.php
│   ├── class.llms.query.php
│   ├── class.llms.query.quiz.attempt.php
│   ├── class.llms.query.user.postmeta.php
│   ├── class.llms.question.manager.php
│   ├── class.llms.question.types.php
│   ├── class.llms.quiz.data.php
│   ├── class.llms.review.php
│   ├── class.llms.roles.php
│   ├── class.llms.session.php
│   ├── class.llms.sidebars.php
│   ├── class.llms.site.php
│   ├── class.llms.student.dashboard.php
│   ├── class.llms.student.query.php
│   ├── class.llms.template.loader.php
│   ├── class.llms.track.php
│   ├── class.llms.tracker.php
│   ├── class.llms.user.permissions.php
│   ├── class.llms.view.manager.php
│   ├── class.llms.voucher.php
│   ├── controllers/
│   │   ├── class-llms-controller-awards.php
│   │   ├── class-llms-controller-checkout.php
│   │   ├── class.llms.controller.achievements.php
│   │   ├── class.llms.controller.admin.quiz.attempts.php
│   │   ├── class.llms.controller.certificates.php
│   │   ├── class.llms.controller.lesson.progression.php
│   │   ├── class.llms.controller.orders.php
│   │   ├── class.llms.controller.quizzes.php
│   │   └── index.php
│   ├── elementor/
│   │   ├── class-llms-elementor-widget-base.php
│   │   ├── class-llms-elementor-widget-course-continue-button.php
│   │   ├── class-llms-elementor-widget-course-instructors.php
│   │   ├── class-llms-elementor-widget-course-meta-info.php
│   │   ├── class-llms-elementor-widget-course-progress.php
│   │   ├── class-llms-elementor-widget-course-syllabus.php
│   │   ├── class-llms-elementor-widget-pricing-table.php
│   │   └── class-llms-elementor-widgets.php
│   ├── emails/
│   │   ├── class.llms.email.engagement.php
│   │   ├── class.llms.email.php
│   │   ├── class.llms.email.reset.password.php
│   │   └── index.php
│   ├── forms/
│   │   ├── class-llms-form-field.php
│   │   ├── class-llms-form-handler.php
│   │   ├── class-llms-form-post-type.php
│   │   ├── class-llms-form-templates.php
│   │   ├── class-llms-form-validator.php
│   │   ├── class-llms-forms-admin-bar.php
│   │   ├── class-llms-forms-classic-editor.php
│   │   ├── class-llms-forms-data.php
│   │   ├── class-llms-forms-dynamic-fields.php
│   │   ├── class-llms-forms-unsupported-versions.php
│   │   ├── class-llms-forms.php
│   │   ├── controllers/
│   │   │   ├── class.llms.controller.account.php
│   │   │   ├── class.llms.controller.login.php
│   │   │   ├── class.llms.controller.registration.php
│   │   │   └── index.php
│   │   └── index.php
│   ├── functions/
│   │   ├── index.php
│   │   ├── llms-functions-access-plans.php
│   │   ├── llms-functions-conditional-tags.php
│   │   ├── llms-functions-content.php
│   │   ├── llms-functions-deprecated.php
│   │   ├── llms-functions-forms.php
│   │   ├── llms-functions-l10n.php
│   │   ├── llms-functions-locale.php
│   │   ├── llms-functions-options.php
│   │   ├── llms-functions-progression.php
│   │   ├── llms-functions-template-view-order.php
│   │   ├── llms-functions-templates-courses.php
│   │   ├── llms-functions-templates-memberships.php
│   │   ├── llms-functions-templates-shared.php
│   │   ├── llms-functions-user-information-fields.php
│   │   ├── llms-functions-wrappers.php
│   │   ├── llms.functions.access.php
│   │   ├── llms.functions.certificate.php
│   │   ├── llms.functions.course.php
│   │   ├── llms.functions.currency.php
│   │   ├── llms.functions.favorite.php
│   │   ├── llms.functions.log.php
│   │   ├── llms.functions.notice.php
│   │   ├── llms.functions.order.php
│   │   ├── llms.functions.page.php
│   │   ├── llms.functions.person.php
│   │   ├── llms.functions.privacy.php
│   │   ├── llms.functions.quiz.php
│   │   ├── llms.functions.template.php
│   │   ├── llms.functions.templates.achievements.php
│   │   ├── llms.functions.templates.certificates.php
│   │   ├── llms.functions.templates.dashboard.php
│   │   ├── llms.functions.templates.dashboard.widgets.php
│   │   ├── llms.functions.templates.loop.php
│   │   ├── llms.functions.templates.pricing.table.php
│   │   ├── llms.functions.templates.privacy.php
│   │   ├── llms.functions.templates.quizzes.php
│   │   ├── llms.functions.updates.php
│   │   ├── llms.functions.user.postmeta.php
│   │   └── updates/
│   │       ├── index.php
│   │       ├── llms-functions-updates-300.php
│   │       ├── llms-functions-updates-303.php
│   │       ├── llms-functions-updates-3120.php
│   │       ├── llms-functions-updates-3130.php
│   │       ├── llms-functions-updates-3160.php
│   │       ├── llms-functions-updates-3280.php
│   │       ├── llms-functions-updates-343.php
│   │       ├── llms-functions-updates-360.php
│   │       ├── llms-functions-updates-380.php
│   │       ├── llms-functions-updates-400.php
│   │       ├── llms-functions-updates-4150.php
│   │       ├── llms-functions-updates-450.php
│   │       ├── llms-functions-updates-500.php
│   │       ├── llms-functions-updates-520.php
│   │       ├── llms-functions-updates-600.php
│   │       ├── llms-functions-updates-6100.php
│   │       ├── llms-functions-updates-630.php
│   │       ├── llms-functions-updates-750.php
│   │       ├── llms-functions-updates-780.php
│   │       ├── llms-functions-updates-785.php
│   │       ├── llms-functions-updates-900.php
│   │       └── llms-functions-updates-921.php
│   ├── index.php
│   ├── integrations/
│   │   ├── class.llms.integration.bbpress.php
│   │   ├── class.llms.integration.buddypress.php
│   │   └── index.php
│   ├── interfaces/
│   │   ├── index.php
│   │   ├── interface.llms.notification.manager.php
│   │   ├── llms.interface.notification.controller.php
│   │   └── llms.interface.post.instructors.php
│   ├── llms-notifications.php
│   ├── llms.functions.core.php
│   ├── llms.spam.functions.php
│   ├── llms.template.functions.php
│   ├── llms.template.hooks.php
│   ├── models/
│   │   ├── class-llms-event.php
│   │   ├── index.php
│   │   ├── model.llms.access.plan.php
│   │   ├── model.llms.add-on.php
│   │   ├── model.llms.coupon.php
│   │   ├── model.llms.course.php
│   │   ├── model.llms.instructor.php
│   │   ├── model.llms.lesson.php
│   │   ├── model.llms.membership.php
│   │   ├── model.llms.notification.php
│   │   ├── model.llms.order.php
│   │   ├── model.llms.post.instructors.php
│   │   ├── model.llms.product.php
│   │   ├── model.llms.question.choice.php
│   │   ├── model.llms.question.php
│   │   ├── model.llms.quiz.attempt.php
│   │   ├── model.llms.quiz.attempt.question.php
│   │   ├── model.llms.quiz.php
│   │   ├── model.llms.section.php
│   │   ├── model.llms.student.php
│   │   ├── model.llms.student.quizzes.php
│   │   ├── model.llms.transaction.php
│   │   ├── model.llms.user.achievement.php
│   │   ├── model.llms.user.certificate.php
│   │   └── model.llms.user.postmeta.php
│   ├── notifications/
│   │   ├── class.llms.notifications.php
│   │   ├── class.llms.notifications.query.php
│   │   ├── controllers/
│   │   │   ├── class.llms.notification.controller.achievement.earned.php
│   │   │   ├── class.llms.notification.controller.certificate.earned.php
│   │   │   ├── class.llms.notification.controller.course.complete.php
│   │   │   ├── class.llms.notification.controller.course.track.complete.php
│   │   │   ├── class.llms.notification.controller.enrollment.php
│   │   │   ├── class.llms.notification.controller.lesson.complete.php
│   │   │   ├── class.llms.notification.controller.manual.payment.due.php
│   │   │   ├── class.llms.notification.controller.payment.retry.php
│   │   │   ├── class.llms.notification.controller.purchase.receipt.php
│   │   │   ├── class.llms.notification.controller.quiz.failed.php
│   │   │   ├── class.llms.notification.controller.quiz.graded.php
│   │   │   ├── class.llms.notification.controller.quiz.passed.php
│   │   │   ├── class.llms.notification.controller.section.complete.php
│   │   │   ├── class.llms.notification.controller.student.welcome.php
│   │   │   ├── class.llms.notification.controller.subscription.cancelled.php
│   │   │   ├── class.llms.notification.controller.upcoming.payment.reminder.php
│   │   │   └── index.php
│   │   ├── index.php
│   │   ├── processors/
│   │   │   ├── class.llms.notification.processor.email.php
│   │   │   └── index.php
│   │   └── views/
│   │       ├── class.llms.notification.view.achievement.earned.php
│   │       ├── class.llms.notification.view.certificate.earned.php
│   │       ├── class.llms.notification.view.course.complete.php
│   │       ├── class.llms.notification.view.course.track.complete.php
│   │       ├── class.llms.notification.view.enrollment.php
│   │       ├── class.llms.notification.view.lesson.complete.php
│   │       ├── class.llms.notification.view.manual.payment.due.php
│   │       ├── class.llms.notification.view.payment.retry.php
│   │       ├── class.llms.notification.view.purchase.receipt.php
│   │       ├── class.llms.notification.view.quiz.failed.php
│   │       ├── class.llms.notification.view.quiz.graded.php
│   │       ├── class.llms.notification.view.quiz.passed.php
│   │       ├── class.llms.notification.view.section.complete.php
│   │       ├── class.llms.notification.view.student.welcome.php
│   │       ├── class.llms.notification.view.subscription.cancelled.php
│   │       ├── class.llms.notification.view.upcoming.payment.reminder.php
│   │       └── index.php
│   ├── privacy/
│   │   ├── class-llms-privacy-erasers.php
│   │   ├── class-llms-privacy-exporters.php
│   │   ├── class-llms-privacy.php
│   │   └── index.php
│   ├── processors/
│   │   ├── class-llms-processor-achievement-sync.php
│   │   ├── class-llms-processor-certificate-sync.php
│   │   ├── class.llms.processor.course.data.php
│   │   ├── class.llms.processor.membership.bulk.enroll.php
│   │   ├── class.llms.processors.php
│   │   └── index.php
│   ├── schemas/
│   │   ├── index.php
│   │   ├── llms-block-templates.php
│   │   ├── llms-db-updates.php
│   │   ├── llms-form-locations.php
│   │   ├── llms-reusable-blocks.php
│   │   └── llms-user-information-fields.php
│   ├── shortcodes/
│   │   ├── class-llms-shortcode-user-info.php
│   │   ├── class.llms.bbp.shortcode.course.forums.list.php
│   │   ├── class.llms.shortcode.checkout.php
│   │   ├── class.llms.shortcode.course.author.php
│   │   ├── class.llms.shortcode.course.continue.button.php
│   │   ├── class.llms.shortcode.course.continue.php
│   │   ├── class.llms.shortcode.course.instructors.php
│   │   ├── class.llms.shortcode.course.meta.info.php
│   │   ├── class.llms.shortcode.course.outline.php
│   │   ├── class.llms.shortcode.course.prerequisites.php
│   │   ├── class.llms.shortcode.course.reviews.php
│   │   ├── class.llms.shortcode.course.syllabus.php
│   │   ├── class.llms.shortcode.courses.php
│   │   ├── class.llms.shortcode.favorites.php
│   │   ├── class.llms.shortcode.hide.content.php
│   │   ├── class.llms.shortcode.lesson.mark.complete.php
│   │   ├── class.llms.shortcode.lesson.navigation.php
│   │   ├── class.llms.shortcode.membership.instructors.php
│   │   ├── class.llms.shortcode.membership.link.php
│   │   ├── class.llms.shortcode.my.account.php
│   │   ├── class.llms.shortcode.my.achievements.php
│   │   ├── class.llms.shortcode.registration.php
│   │   ├── class.llms.shortcodes.blocks.php
│   │   ├── class.llms.shortcodes.php
│   │   └── index.php
│   ├── spam/
│   │   ├── class-llms-akismet.php
│   │   ├── class-llms-captcha.php
│   │   ├── class-llms-recaptcha.php
│   │   └── class-llms-turnstile.php
│   ├── theme-support/
│   │   ├── class-llms-theme-support.php
│   │   ├── class-llms-twenty-nineteen.php
│   │   ├── class-llms-twenty-twenty-one.php
│   │   ├── class-llms-twenty-twenty-two.php
│   │   ├── class-llms-twenty-twenty.php
│   │   └── index.php
│   ├── traits/
│   │   ├── llms-trait-audio-video-embed.php
│   │   ├── llms-trait-award-default-images.php
│   │   ├── llms-trait-award-templates-post-list-table.php
│   │   ├── llms-trait-earned-engagement-reporting-table.php
│   │   ├── llms-trait-sales-page.php
│   │   ├── llms-trait-singleton.php
│   │   ├── llms-trait-student-awards.php
│   │   └── llms-trait-user-engagement-type.php
│   └── widgets/
│       ├── class.llms.bbp.widget.course.forums.list.php
│       ├── class.llms.widget.course.progress.php
│       ├── class.llms.widget.course.syllabus.php
│       ├── class.llms.widget.php
│       ├── class.llms.widgets.php
│       └── index.php
├── index.php
├── languages/
│   ├── README.md
│   ├── countries-address-info.php
│   ├── countries.php
│   ├── currencies.php
│   ├── currency-symbols.php
│   └── states.php
├── lerna.json
├── libraries/
│   ├── README.md
│   └── index.php
├── lifterlms.php
├── package.json
├── packages/
│   ├── README.md
│   ├── brand/
│   │   ├── README.md
│   │   ├── package.json
│   │   └── sass/
│   │       ├── brand.scss
│   │       ├── colors.scss
│   │       └── typography.scss
│   ├── components/
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── button-group-control/
│   │       │   ├── index.js
│   │       │   └── test/
│   │       │       └── index.js
│   │       ├── copy-button/
│   │       │   └── index.js
│   │       ├── index.js
│   │       ├── post-select/
│   │       │   └── index.js
│   │       ├── search-control/
│   │       │   ├── base-search-control.js
│   │       │   ├── defaults.js
│   │       │   ├── index.js
│   │       │   ├── post-search-control.js
│   │       │   ├── styled-base-control.js
│   │       │   └── user-search-control.js
│   │       └── spinner/
│   │           ├── .eslintrc.js
│   │           ├── constants.js
│   │           ├── index.js
│   │           ├── styles.js
│   │           ├── test/
│   │           │   ├── __MOCKS__/
│   │           │   │   └── jquery.js
│   │           │   ├── __snapshots__/
│   │           │   │   ├── index.test.js.snap
│   │           │   │   └── utils.test.js.snap
│   │           │   ├── index.test.js
│   │           │   └── utils.test.js
│   │           └── utils.js
│   ├── dev/
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── .eslintrc.js
│   │   │   ├── cmds/
│   │   │   │   ├── changelog/
│   │   │   │   │   ├── add.js
│   │   │   │   │   ├── index.js
│   │   │   │   │   ├── list.js
│   │   │   │   │   ├── validate.js
│   │   │   │   │   ├── version.js
│   │   │   │   │   └── write.js
│   │   │   │   ├── docgen.js
│   │   │   │   ├── meta/
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── parse.js
│   │   │   │   ├── pot.js
│   │   │   │   ├── readme.js
│   │   │   │   ├── release/
│   │   │   │   │   ├── archive.js
│   │   │   │   │   ├── create.js
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── prepare.js
│   │   │   │   └── update-version.js
│   │   │   ├── index.js
│   │   │   └── utils/
│   │   │       ├── changelog-entry.js
│   │   │       ├── configs.js
│   │   │       ├── create-dist-file.js
│   │   │       ├── determine-version-increment.js
│   │   │       ├── exec-sync.js
│   │   │       ├── get-archive-filename.js
│   │   │       ├── get-changelog-entries.js
│   │   │       ├── get-changelog-for-version.js
│   │   │       ├── get-changelog-options.js
│   │   │       ├── get-current-version.js
│   │   │       ├── get-default.js
│   │   │       ├── get-next-version.js
│   │   │       ├── get-project-privacy.js
│   │   │       ├── get-project-slug.js
│   │   │       ├── index.js
│   │   │       ├── log-result.js
│   │   │       ├── pare-main-file-metadata.js
│   │   │       ├── parse-changelog-file.js
│   │   │       ├── parse-issue-string.js
│   │   │       ├── push-dist-file.js
│   │   │       ├── repo-links.js
│   │   │       └── validate-changelog.js
│   │   └── test/
│   │       └── utils/
│   │           ├── configs.test.js
│   │           ├── determine-version-increment.test.js
│   │           ├── exec-sync.test.js
│   │           ├── get-archive-filename.test.js
│   │           ├── get-changelog-for-version.test.js
│   │           ├── get-next-version.test.js
│   │           ├── get-project-privacy.test.js
│   │           ├── get-project-slug.test.js
│   │           ├── parse-changelog-file.test.js
│   │           ├── parse-issue-string.test.js
│   │           ├── repo-links.test.js
│   │           └── validate-changelog.test.js
│   ├── fontawesome/
│   │   ├── .eslintrc.js
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── bin/
│   │   │   ├── .eslintrc.js
│   │   │   ├── metadata.js
│   │   │   └── svg.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── components/
│   │       │   ├── icon-list.js
│   │       │   ├── icon-picker.js
│   │       │   └── icon.js
│   │       ├── fontawesome.scss
│   │       ├── index.js
│   │       └── metadata.json
│   ├── icons/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── docs/
│   │   │   ├── app.js
│   │   │   ├── generate.js
│   │   │   └── index.html
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.js
│   │       └── lifterlms.js
│   ├── llms-e2e-test-utils/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── .eslintrc.js
│   │       ├── activate-theme.js
│   │       ├── clear-blocks.js
│   │       ├── click-and-wait.js
│   │       ├── click-element-by-text.js
│   │       ├── click.js
│   │       ├── create-access-plan.js
│   │       ├── create-certificate.js
│   │       ├── create-coupon.js
│   │       ├── create-course.js
│   │       ├── create-engagement.js
│   │       ├── create-membership.js
│   │       ├── create-post.js
│   │       ├── create-user.js
│   │       ├── create-voucher.js
│   │       ├── dismiss-editor-welcome-guide.js
│   │       ├── enroll-student.js
│   │       ├── fill-field.js
│   │       ├── find-element-by-text.js
│   │       ├── get-all-blocks.js
│   │       ├── get-post-title.js
│   │       ├── get-wp-version.js
│   │       ├── highlight-node.js
│   │       ├── import-course.js
│   │       ├── index.js
│   │       ├── login-student.js
│   │       ├── logout-user.js
│   │       ├── open-sidebar-panel-tab.js
│   │       ├── publish-post.js
│   │       ├── register-student.js
│   │       ├── run-setup-wizard.js
│   │       ├── select2-select.js
│   │       ├── set-checkbox-setting.js
│   │       ├── set-select2-option.js
│   │       ├── toggle-open-registration.js
│   │       ├── toggle-sidebar-panel.js
│   │       ├── update-post.js
│   │       ├── visit-page.js
│   │       ├── visit-post-permalink.js
│   │       ├── visit-settings-page.js
│   │       └── wp-version-compare.js
│   ├── quill-wordcount-module/
│   │   ├── .eslintrc.js
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── create-container.js
│   │       ├── format-number.js
│   │       ├── get-counter-text-color.js
│   │       ├── index.js
│   │       ├── module.js
│   │       └── test/
│   │           ├── __snapshots__/
│   │           │   ├── create-container.test.js.snap
│   │           │   └── module.test.js.snap
│   │           ├── create-container.test.js
│   │           ├── format-number.test.js
│   │           ├── get-counter-text-color.js
│   │           ├── index.test.js
│   │           └── module.test.js
│   ├── scripts/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── config/
│   │   │   ├── .eslintrc.js
│   │   │   ├── blocks-webpack.config.js
│   │   │   ├── import-resolver.js
│   │   │   ├── jest-unit.config.js
│   │   │   └── webpack.config.js
│   │   ├── e2e/
│   │   │   ├── bootstrap.js
│   │   │   ├── jest-puppeteer.config.js
│   │   │   ├── jest.config.js
│   │   │   └── sequencer.js
│   │   └── package.json
│   └── utils/
│       ├── .llmsdev.yml
│       ├── .npmrc
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── babel.config.js
│       ├── package.json
│       └── src/
│           ├── formatting/
│           │   ├── index.js
│           │   ├── test/
│           │   │   └── index.js
│           │   ├── trailing-slash-it.js
│           │   └── untrailing-slash-it.js
│           ├── index.js
│           └── url/
│               ├── get-admin-url.js
│               ├── index.js
│               └── test/
│                   └── get-admin-url.test.js
├── phpcs.xml
├── phpmd.xml
├── phpunit.xml.dist
├── sample-data/
│   ├── index.php
│   └── sample-course.json
├── src/
│   ├── blocks/
│   │   ├── access-plan-button/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── certificate-title/
│   │   │   ├── block.json
│   │   │   ├── edit.jsx
│   │   │   ├── icon.jsx
│   │   │   ├── index.jsx
│   │   │   └── save.jsx
│   │   ├── checkout/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-author/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-continue/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-meta-info/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-outline/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-prerequisites/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-reviews/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-syllabus/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── courses/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── login/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── memberships/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── my-account/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── my-achievements/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── navigation-link/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── pricing-table/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   └── registration/
│   │       ├── block.json
│   │       ├── icon.jsx
│   │       └── index.jsx
│   ├── js/
│   │   ├── .eslintrc.js
│   │   ├── admin-addons.js
│   │   ├── admin-award-certificate.js
│   │   ├── admin-certificate-editor/
│   │   │   ├── document-settings.js
│   │   │   ├── edit-certificate.js
│   │   │   ├── editor.js
│   │   │   ├── i18n.js
│   │   │   ├── index.js
│   │   │   ├── merge-codes.js
│   │   │   ├── migrate.js
│   │   │   ├── modify-blocks.js
│   │   │   ├── notices.js
│   │   │   ├── plugin/
│   │   │   │   ├── background-control.js
│   │   │   │   ├── margins-control.js
│   │   │   │   ├── orientation-control.js
│   │   │   │   ├── sequential-id-control.js
│   │   │   │   ├── size-control.js
│   │   │   │   └── title-control.js
│   │   │   ├── post-status-info/
│   │   │   │   ├── award-button.js
│   │   │   │   ├── award-check.js
│   │   │   │   ├── index.js
│   │   │   │   ├── reset-template-button.js
│   │   │   │   └── reset-template-check.js
│   │   │   └── user-settings.js
│   │   ├── admin-certificate-editor.js
│   │   ├── admin-elementor-editor.js
│   │   ├── admin-media-protection-block-protect.js
│   │   ├── components.js
│   │   ├── icons.js
│   │   ├── quill-wordcount.js
│   │   ├── spinner.js
│   │   ├── util/
│   │   │   ├── README.md
│   │   │   ├── award-certificate-button/
│   │   │   │   ├── create.js
│   │   │   │   ├── index.js
│   │   │   │   ├── message.js
│   │   │   │   ├── test/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.js.snap
│   │   │   │   │   └── index.js
│   │   │   │   └── urls.js
│   │   │   ├── edit-certificate-title.js
│   │   │   └── index.js
│   │   └── utils.js
│   └── scss/
│       ├── admin-addons.scss
│       └── fontawesome.scss
├── templates/
│   ├── achievements/
│   │   ├── loop.php
│   │   └── template.php
│   ├── admin/
│   │   ├── analytics/
│   │   │   └── analytics.php
│   │   ├── notices/
│   │   │   └── staging.php
│   │   ├── post-types/
│   │   │   ├── order-transactions.php
│   │   │   └── students.php
│   │   ├── reporting/
│   │   │   ├── nav-filters.php
│   │   │   ├── reporting.php
│   │   │   └── tabs/
│   │   │       ├── courses/
│   │   │       │   ├── course.php
│   │   │       │   ├── overview.php
│   │   │       │   └── students.php
│   │   │       ├── memberships/
│   │   │       │   ├── membership.php
│   │   │       │   ├── overview.php
│   │   │       │   └── students.php
│   │   │       ├── quizzes/
│   │   │       │   ├── attempt.php
│   │   │       │   ├── attempts.php
│   │   │       │   ├── non-attempts.php
│   │   │       │   ├── overview.php
│   │   │       │   └── quiz.php
│   │   │       ├── students/
│   │   │       │   ├── achievements.php
│   │   │       │   ├── certificates.php
│   │   │       │   ├── courses-course.php
│   │   │       │   ├── courses.php
│   │   │       │   ├── information.php
│   │   │       │   ├── memberships.php
│   │   │       │   ├── quiz_attempts.php
│   │   │       │   ├── student.php
│   │   │       │   └── students.php
│   │   │       └── widgets.php
│   │   └── user-edit.php
│   ├── archive-course.php
│   ├── archive-llms_membership.php
│   ├── block-templates/
│   │   ├── archive-course.html
│   │   ├── archive-llms_membership.html
│   │   ├── single-no-access.html
│   │   ├── taxonomy-course_cat.html
│   │   ├── taxonomy-course_difficulty.html
│   │   ├── taxonomy-course_tag.html
│   │   ├── taxonomy-course_track.html
│   │   ├── taxonomy-membership_cat.html
│   │   └── taxonomy-membership_tag.html
│   ├── certificates/
│   │   ├── actions.php
│   │   ├── content-legacy.php
│   │   ├── content.php
│   │   ├── dynamic-styles.php
│   │   ├── footer.php
│   │   ├── header.php
│   │   ├── loop.php
│   │   ├── preview.php
│   │   └── template.php
│   ├── checkout/
│   │   ├── form-checkout.php
│   │   ├── form-confirm-payment.php
│   │   ├── form-coupon.php
│   │   ├── form-gateways.php
│   │   ├── form-summary.php
│   │   └── form-switch-source.php
│   ├── content-certificate.php
│   ├── content-no-access-after.php
│   ├── content-no-access-before.php
│   ├── content-no-access.php
│   ├── content-single-course-after.php
│   ├── content-single-course-before.php
│   ├── content-single-lesson-after.php
│   ├── content-single-lesson-before.php
│   ├── content-single-membership-after.php
│   ├── content-single-membership-before.php
│   ├── content-single-question.php
│   ├── content-single-quiz-after.php
│   ├── content-single-quiz-before.php
│   ├── course/
│   │   ├── audio.php
│   │   ├── author.php
│   │   ├── categories.php
│   │   ├── complete-lesson-link.php
│   │   ├── difficulty.php
│   │   ├── favorite.php
│   │   ├── full-description.php
│   │   ├── length.php
│   │   ├── lesson-count.php
│   │   ├── lesson-navigation.php
│   │   ├── lesson-preview.php
│   │   ├── meta-wrapper-end.php
│   │   ├── meta-wrapper-start.php
│   │   ├── outline-list-small.php
│   │   ├── parent-course.php
│   │   ├── prerequisites.php
│   │   ├── progress.php
│   │   ├── short-description.php
│   │   ├── syllabus.php
│   │   ├── tags.php
│   │   ├── title.php
│   │   ├── tracks.php
│   │   └── video.php
│   ├── emails/
│   │   ├── footer.php
│   │   ├── header.php
│   │   ├── reset-password.php
│   │   └── template.php
│   ├── global/
│   │   ├── form-login.php
│   │   ├── form-registration.php
│   │   ├── sidebar.php
│   │   ├── wrapper-end.php
│   │   └── wrapper-start.php
│   ├── lesson/
│   │   ├── audio.php
│   │   └── video.php
│   ├── loop/
│   │   ├── author.php
│   │   ├── content.php
│   │   ├── enroll-date.php
│   │   ├── enroll-status.php
│   │   ├── featured-image.php
│   │   ├── featured-pricing.php
│   │   ├── loop-end.php
│   │   ├── loop-start.php
│   │   ├── none-found.php
│   │   └── pagination.php
│   ├── loop-main.php
│   ├── loop.php
│   ├── membership/
│   │   ├── audio.php
│   │   ├── full-description.php
│   │   ├── instructors.php
│   │   ├── price.php
│   │   ├── title.php
│   │   └── video.php
│   ├── myaccount/
│   │   ├── dashboard-section.php
│   │   ├── dashboard.php
│   │   ├── form-edit-account.php
│   │   ├── form-lost-password.php
│   │   ├── form-redeem-voucher.php
│   │   ├── header.php
│   │   ├── my-favorites.php
│   │   ├── my-grades-single-table.php
│   │   ├── my-grades-single.php
│   │   ├── my-grades.php
│   │   ├── my-notifications.php
│   │   ├── my-orders.php
│   │   ├── navigation.php
│   │   ├── view-order-actions.php
│   │   ├── view-order-information.php
│   │   ├── view-order-transactions.php
│   │   └── view-order.php
│   ├── notices/
│   │   ├── debug.php
│   │   ├── error.php
│   │   ├── notice.php
│   │   └── success.php
│   ├── notifications/
│   │   └── basic.php
│   ├── product/
│   │   ├── access-plan-button.php
│   │   ├── access-plan-description.php
│   │   ├── access-plan-feature.php
│   │   ├── access-plan-pricing.php
│   │   ├── access-plan-restrictions.php
│   │   ├── access-plan-title.php
│   │   ├── access-plan-trial.php
│   │   ├── access-plan.php
│   │   ├── free-enroll-form.php
│   │   ├── not-purchasable.php
│   │   └── pricing-table.php
│   ├── quiz/
│   │   ├── meta-information.php
│   │   ├── questions/
│   │   │   ├── content-choice.php
│   │   │   ├── content-picture_choice.php
│   │   │   ├── content-true_false.php
│   │   │   ├── description.php
│   │   │   ├── image.php
│   │   │   ├── video.php
│   │   │   ├── wrapper-end.php
│   │   │   └── wrapper-start.php
│   │   ├── quiz-wrapper-end.php
│   │   ├── quiz-wrapper-start.php
│   │   ├── results-attempt-questions-list.php
│   │   ├── results-attempt.php
│   │   ├── results.php
│   │   ├── return-to-lesson.php
│   │   └── start-button.php
│   ├── shared/
│   │   └── instructors.php
│   ├── single-certificate.php
│   ├── single-lesson-focus.php
│   ├── single-no-access.php
│   ├── taxonomy-course_cat.php
│   ├── taxonomy-course_difficulty.php
│   ├── taxonomy-course_tag.php
│   ├── taxonomy-course_track.php
│   ├── taxonomy-membership_cat.php
│   └── taxonomy-membership_tag.php
├── tests/
│   ├── assets/
│   │   ├── example-style-1.css
│   │   ├── example-style-2.css
│   │   ├── example-style.css
│   │   ├── import-error.json
│   │   ├── import-fake-generator.json
│   │   ├── import-with-prerequisites.json
│   │   ├── import-with-quiz.json
│   │   ├── import-with-restrictions.json
│   │   ├── lifterlms-en_US-cd71ad734c92669051f6fd28eb90dfd4.json
│   │   ├── lifterlms-en_US.mo
│   │   ├── lifterlms-en_US.po
│   │   └── lifterlms-mock-addon.php
│   ├── bin/
│   │   └── setup-e2e.sh
│   ├── e2e/
│   │   ├── README.md
│   │   └── tests/
│   │       ├── activate/
│   │       │   └── bootstrap.test.js
│   │       ├── checkout/
│   │       │   └── coupon.test.js
│   │       ├── page-restrictions/
│   │       │   ├── course.test.js
│   │       │   └── sitewide-membership.test.js
│   │       ├── settings/
│   │       │   └── copy-prevention.test.js
│   │       ├── student/
│   │       │   ├── __snapshots__/
│   │       │   │   ├── open-registration.test.js.snap
│   │       │   │   └── voucher.test.js.snap
│   │       │   ├── login.test.js
│   │       │   ├── open-registration.test.js
│   │       │   └── voucher.test.js
│   │       └── view-manager/
│   │           ├── __snapshots__/
│   │           │   └── view-manager.test.js.snap
│   │           └── view-manager.test.js
│   └── phpunit/
│       ├── README.md
│       ├── bootstrap.php
│       ├── framework/
│       │   ├── class-llms-admin-tool-test-case.php
│       │   ├── class-llms-notification-test-case.php
│       │   ├── class-llms-payment-gateway-mock.php
│       │   ├── class-llms-post-model-unit-test-case.php
│       │   ├── class-llms-post-type-metabox-test-case.php
│       │   ├── class-llms-settings-page-test-case.php
│       │   ├── class-llms-shortcode-test-case.php
│       │   └── class-llms-unit-test-case.php
│       └── unit-tests/
│           ├── abstracts/
│           │   ├── class-llms-test-abstract-admin-metabox.php
│           │   ├── class-llms-test-abstract-admin-tool.php
│           │   ├── class-llms-test-abstract-database-query.php
│           │   ├── class-llms-test-abstract-exportable-abmin-table.php
│           │   ├── class-llms-test-abstract-generator-posts.php
│           │   ├── class-llms-test-abstract-integration.php
│           │   ├── class-llms-test-abstract-notification-view.php
│           │   ├── class-llms-test-abstract-options-data.php
│           │   ├── class-llms-test-abstract-payment-gateway.php
│           │   ├── class-llms-test-abstract-post-model.php
│           │   ├── class-llms-test-abstract-posts-query.php
│           │   ├── class-llms-test-abstract-query.php
│           │   ├── class-llms-test-abstract-session-data.php
│           │   └── class-llms-test-abstract-session-database-handler.php
│           ├── admin/
│           │   ├── class-llms-test-admin-assets.php
│           │   ├── class-llms-test-admin-builder.php
│           │   ├── class-llms-test-admin-import.php
│           │   ├── class-llms-test-admin-menus.php
│           │   ├── class-llms-test-admin-notices.php
│           │   ├── class-llms-test-admin-page-status.php
│           │   ├── class-llms-test-admin-post-types.php
│           │   ├── class-llms-test-admin-profile.php
│           │   ├── class-llms-test-admin-review.php
│           │   ├── class-llms-test-admin-settings.php
│           │   ├── class-llms-test-admin-setup-wizard.php
│           │   ├── class-llms-test-admin-users-table.php
│           │   ├── class-llms-test-export-api.php
│           │   ├── class-llms-test-sendwp.php
│           │   ├── post-types/
│           │   │   ├── class-llms-test-llms-admin-meta-boxes.php
│           │   │   ├── meta-boxes/
│           │   │   │   ├── class-llms-test-meta-box-access.php
│           │   │   │   ├── class-llms-test-meta-box-achievement-sync.php
│           │   │   │   ├── class-llms-test-meta-box-achievement.php
│           │   │   │   ├── class-llms-test-meta-box-award-engagement-submit.php
│           │   │   │   ├── class-llms-test-meta-box-certificate-sync.php
│           │   │   │   ├── class-llms-test-meta-box-certificate.php
│           │   │   │   ├── class-llms-test-meta-box-lesson.php
│           │   │   │   ├── class-llms-test-meta-box-order-details.php
│           │   │   │   ├── class-llms-test-meta-box-order-enrollment.php
│           │   │   │   ├── class-llms-test-meta-box-order-submit.php
│           │   │   │   └── fields/
│           │   │   │       └── class-llms-test-meta-box-textarea-tags.php
│           │   │   └── post-tables/
│           │   │       └── class-llms-admin-post-table-certificates.php
│           │   ├── reporting/
│           │   │   ├── __snapshots__/
│           │   │   │   ├── admin-reporting-output_widget-test-a.txt
│           │   │   │   ├── admin-reporting-output_widget-test-b.txt
│           │   │   │   ├── admin-reporting-output_widget-test-c.txt
│           │   │   │   ├── admin-reporting-output_widget-test-d.txt
│           │   │   │   ├── admin-reporting-output_widget-test-e.txt
│           │   │   │   ├── admin-reporting-output_widget-test-f.txt
│           │   │   │   ├── admin-reporting-output_widget-test-g.txt
│           │   │   │   └── admin-reporting-output_widget-test-h.txt
│           │   │   └── class-llms-test-admin-reporting.php
│           │   ├── settings/
│           │   │   ├── class-llms-test-settings-accounts.php
│           │   │   ├── class-llms-test-settings-engagements.php
│           │   │   └── class-llms-test-settings-page.php
│           │   └── tools/
│           │       ├── class-llms-test-admin-tool-batch-eraser.php
│           │       ├── class-llms-test-admin-tool-clear-sessions.php
│           │       ├── class-llms-test-admin-tool-install-forms.php
│           │       ├── class-llms-test-admin-tool-limited-billing-order-locator.php
│           │       ├── class-llms-test-admin-tool-recurring-payment-rescheduler.php
│           │       ├── class-llms-test-admin-tool-reset-automatic-payments.php
│           │       └── class-llms-test-admin-tool-wipe-legacy-account-options.php
│           ├── ajax/
│           │   ├── class-llms-test-ajax-handler-coupons.php
│           │   └── class-llms-test-ajax-handler-quizzes.php
│           ├── class-llms-test-admin-media-protection-attachment-settings.php
│           ├── class-llms-test-ajax-handler.php
│           ├── class-llms-test-assets.php
│           ├── class-llms-test-awards-query.php
│           ├── class-llms-test-block-library.php
│           ├── class-llms-test-block-templates.php
│           ├── class-llms-test-blocks.php
│           ├── class-llms-test-cache-helper.php
│           ├── class-llms-test-certificates.php
│           ├── class-llms-test-cli.php
│           ├── class-llms-test-comments.php
│           ├── class-llms-test-db-upgrader.php
│           ├── class-llms-test-engagement-handler.php
│           ├── class-llms-test-engagements.php
│           ├── class-llms-test-events-core.php
│           ├── class-llms-test-events-query.php
│           ├── class-llms-test-events.php
│           ├── class-llms-test-frontend-assets.php
│           ├── class-llms-test-functions-access.php
│           ├── class-llms-test-functions-privacy.php
│           ├── class-llms-test-functions-quiz.php
│           ├── class-llms-test-gateway-manual.php
│           ├── class-llms-test-generator-courses.php
│           ├── class-llms-test-generator.php
│           ├── class-llms-test-grades.php
│           ├── class-llms-test-hasher.php
│           ├── class-llms-test-helper.php
│           ├── class-llms-test-https.php
│           ├── class-llms-test-install.php
│           ├── class-llms-test-integrations.php
│           ├── class-llms-test-llms-dom-document.php
│           ├── class-llms-test-main-class.php
│           ├── class-llms-test-mime-type-extractor.php
│           ├── class-llms-test-order-generator.php
│           ├── class-llms-test-payment-gateway-integrations.php
│           ├── class-llms-test-payment-gateways.php
│           ├── class-llms-test-playnice.php
│           ├── class-llms-test-post-instructors.php
│           ├── class-llms-test-post-relationships.php
│           ├── class-llms-test-post-types.php
│           ├── class-llms-test-prevent-concurrent-logins.php
│           ├── class-llms-test-query.php
│           ├── class-llms-test-quiz-attempt-query.php
│           ├── class-llms-test-rest-fields.php
│           ├── class-llms-test-rest.php
│           ├── class-llms-test-review.php
│           ├── class-llms-test-roles.php
│           ├── class-llms-test-session.php
│           ├── class-llms-test-sessions.php
│           ├── class-llms-test-shortcodes.php
│           ├── class-llms-test-site.php
│           ├── class-llms-test-staging.php
│           ├── class-llms-test-student-query.php
│           ├── class-llms-test-template-functions.php
│           ├── class-llms-test-template-loader.php
│           ├── class-llms-test-user-postmeta-query.php
│           ├── class-llms-test-view-manager.php
│           ├── controllers/
│           │   ├── class-llms-test-conroller-quizzes.php
│           │   ├── class-llms-test-controller-account.php
│           │   ├── class-llms-test-controller-achievements.php
│           │   ├── class-llms-test-controller-awards.php
│           │   ├── class-llms-test-controller-certificates.php
│           │   ├── class-llms-test-controller-checkout.php
│           │   ├── class-llms-test-controller-lesson-progression.php
│           │   ├── class-llms-test-controller-login.php
│           │   ├── class-llms-test-controller-orders.php
│           │   └── class-llms-test-controller-registration.php
│           ├── forms/
│           │   ├── class-llms-test-form-field.php
│           │   ├── class-llms-test-form-handler.php
│           │   ├── class-llms-test-form-post-type.php
│           │   ├── class-llms-test-form-templates.php
│           │   ├── class-llms-test-form-validator.php
│           │   ├── class-llms-test-forms-admin-bar.php
│           │   ├── class-llms-test-forms-classic-editor.php
│           │   ├── class-llms-test-forms-data.php
│           │   ├── class-llms-test-forms-dynamic-fields.php
│           │   ├── class-llms-test-forms-unsupported-versions.php
│           │   └── class-llms-test-forms.php
│           ├── functions/
│           │   ├── class-llms-test-functions-access-plans.php
│           │   ├── class-llms-test-functions-admin.php
│           │   ├── class-llms-test-functions-certificates.php
│           │   ├── class-llms-test-functions-conditional-tags.php
│           │   ├── class-llms-test-functions-content.php
│           │   ├── class-llms-test-functions-core.php
│           │   ├── class-llms-test-functions-currency.php
│           │   ├── class-llms-test-functions-deprecated.php
│           │   ├── class-llms-test-functions-forms.php
│           │   ├── class-llms-test-functions-l10n.php
│           │   ├── class-llms-test-functions-locale.php
│           │   ├── class-llms-test-functions-logs.php
│           │   ├── class-llms-test-functions-options.php
│           │   ├── class-llms-test-functions-order.php
│           │   ├── class-llms-test-functions-page.php
│           │   ├── class-llms-test-functions-person.php
│           │   ├── class-llms-test-functions-progression.php
│           │   ├── class-llms-test-functions-template.php
│           │   ├── class-llms-test-functions-templates-certificates.php
│           │   ├── class-llms-test-functions-templates-dasbhoard.php
│           │   ├── class-llms-test-functions-templates-loop.php
│           │   ├── class-llms-test-functions-templates-pricing-table.php
│           │   ├── class-llms-test-functions-templates-vier-order.php
│           │   ├── class-llms-test-functions-updates.php
│           │   ├── class-llms-test-functions-user-information-fields.php
│           │   ├── class-llms-test-functions-user-postmeta.php
│           │   ├── class-llms-test-template-functions.php
│           │   └── updates/
│           │       ├── class-llms-test-functions-updates-400.php
│           │       ├── class-llms-test-functions-updates-4150.php
│           │       ├── class-llms-test-functions-updates-450.php
│           │       ├── class-llms-test-functions-updates-500.php
│           │       ├── class-llms-test-functions-updates-520.php
│           │       ├── class-llms-test-functions-updates-600.php
│           │       ├── class-llms-test-functions-updates-6100.php
│           │       └── class-llms-test-functions-updates-630.php
│           ├── functions-templates/
│           │   ├── class-llms-test-functions-templates-courses.php
│           │   ├── class-llms-test-functions-templates-memberships.php
│           │   └── class-llms-test-functions-templates-pricing-table.php
│           ├── integrations/
│           │   ├── class-llms-test-integration-bbpress.php
│           │   └── class-llms-test-integration-buddypress.php
│           ├── models/
│           │   ├── class-llms-test-event.php
│           │   ├── class-llms-test-instructor.php
│           │   ├── class-llms-test-model-llms-access-plan.php
│           │   ├── class-llms-test-model-llms-add-on.php
│           │   ├── class-llms-test-model-llms-coupon.php
│           │   ├── class-llms-test-model-llms-course.php
│           │   ├── class-llms-test-model-llms-lesson.php
│           │   ├── class-llms-test-model-llms-membership.php
│           │   ├── class-llms-test-model-llms-order.php
│           │   ├── class-llms-test-model-llms-product.php
│           │   ├── class-llms-test-model-llms-question.php
│           │   ├── class-llms-test-model-llms-quiz-attempt.php
│           │   ├── class-llms-test-model-llms-quiz.php
│           │   ├── class-llms-test-model-llms-section.php
│           │   ├── class-llms-test-model-llms-student-quizzes.php
│           │   ├── class-llms-test-model-llms-student.php
│           │   ├── class-llms-test-model-llms-transaction.php
│           │   ├── class-llms-test-model-llms-user-achievement.php
│           │   └── class-llms-test-model-llms-user-certificate.php
│           ├── notifications/
│           │   ├── class-llms-test-notification-achievement-earned.php
│           │   ├── class-llms-test-notification-certificate-earned.php
│           │   ├── class-llms-test-notifications-query.php
│           │   ├── class-llms-test-notifications.php
│           │   └── controllers/
│           │       └── class-llms-test-notification-controller-upcoming-payment-reminder.php
│           ├── processors/
│           │   ├── class-llms-test-processor-awarded-achievements-bulk-sync.php
│           │   ├── class-llms-test-processor-awarded-certificates-bulk-sync.php
│           │   ├── class-llms-test-processor-course-data.php
│           │   └── class-llms-test-processors.php
│           ├── shortcodes/
│           │   ├── class-llms-test-shortcode-checkout.php
│           │   ├── class-llms-test-shortcode-course-progress.php
│           │   ├── class-llms-test-shortcode-hide-content.php
│           │   └── class-llms-test-shortcode-user-info.php
│           ├── tables/
│           │   ├── class-llms-test-table-course-students.php
│           │   ├── class-llms-test-table-quizzes.php
│           │   └── class-llms-test-table-students.php
│           ├── theme-support/
│           │   ├── class-llms-test-theme-support.php
│           │   ├── class-llms-test-twenty-twenty-one.php
│           │   ├── class-llms-test-twenty-twenty-two.php
│           │   └── class-llms-test-twenty-twenty.php
│           ├── traits/
│           │   ├── llms-test-trait-audio-video-embed.php
│           │   ├── llms-test-trait-award-default-images.php
│           │   ├── llms-test-trait-award-templates-post-list-table.php
│           │   ├── llms-test-trait-sales-page.php
│           │   ├── llms-test-trait-singleton.php
│           │   ├── llms-test-trait-student-awards.php
│           │   └── llms-test-trait-user-engagement-type.php
│           └── user/
│               ├── class-llms-test-abstract-user-data.php
│               ├── class-llms-test-person-handler.php
│               ├── class-llms-test-student-quizzes.php
│               ├── class-llms-test-student.php
│               └── class-llms-test-user-permissions.php
├── uninstall.php
└── webpack.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .codeclimate.yml
================================================
vesion: '2'

exclude_patterns:
  # Ignore dot directories.
  - .changelogs/
  - .config/
  - .github/
  - .source/
  - .wordpress-org
  - ._private/
  # Misc non-code directories.
  - dist/
  - docs/
  - gulpfile.js/
  - gulpfile.js
  - i18n/
  - languages/
  - libraries/
  - tests/
  - tmp/
  # Included vendor packages.
  - '**/vendor/'
  - '**/node_modules/'
  # Minified scripts.
  - '**/*.min.js'
  - '**/index.php'
  - '**/*.asset.php'
  - assets/js/llms.js
  - assets/js/llms-admin-addons.js
  - assets/js/llms-builder.js
  - assets/js/llms-components.js
  - assets/js/llms-icons.js
  - assets/js/llms-metaboxes.js
  - assets/js/llms-utils.js


================================================
FILE: .cursor/BUGBOT.md
================================================
Do not review pull requests authored by dependabot[bot] or any automated dependency update bots.


================================================
FILE: .editorconfig
================================================
###
#
# This file is deployed into this repository via the "Sync Organization Files" workflow.
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/.editorconfig}
#
###

# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org

# WordPress Coding Standards
# https://developer.wordpress.org/coding-standards/wordpress-coding-standards/

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
tab_width = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true

[*.{md,txt}]
insert_final_newline = false
trim_trailing_whitespace = false

[*.{md,json,yml,yml.template}]
indent_style = space
indent_size = 2


================================================
FILE: .eslintrc.js
================================================
/**
 * ESlint config
 *
 * @package LifterLMS/Scripts/Dev
 *
 * @since Unknown
 * @version Unknown
 */

const config = require( '@lifterlms/scripts/config/.eslintrc.js' );

module.exports = config;


================================================
FILE: .github/CODEOWNERS
================================================
* @brianhogg

# Full Site Editing.
includes/class-llms-block-templates.php @ideadude


================================================
FILE: .github/CONTRIBUTING.md
================================================
Contributing to LifterLMS
=========================

We welcome and encourage contributions from the community. If you'd like to contribute to LifterLMS there are a few ways to do so. Here's our guidelines for contributions:

*Please Note GitHub is for bug reports and contributions only! If you have a support question or a request for a customization this is not the right place to post it. Please refer to [LifterLMS Support](https://lifterlms.com/my-account/my-tickets) or the [community forums](https://wordpress.org/support/plugin/lifterlms). If you're looking for help customizing LifterLMS, please consider hiring a [LifterLMS Expert](https://lifterlms.com/docs/do-you-have-any-recommended-developers-who-can-modifycustomize-lifterlms/).*


### Ways to Contribute

+ [Submit bug and issues reports](#reporting-a-bug-or-issue)
+ [Contribute new features](#contributing-new-features)
+ [Contribute new code or bug fixes / patches](#contributing-code)
+ [Translate and localize LifterLMS](#contribute-translations)


### Reporting a Bug or Issue

Bugs and issues can be reported at [https://github.com/gocodebox/lifterlms/issues/new/choose](https://github.com/gocodebox/lifterlms/issues/new).

Before reporting a bug, [search existing issues](https://github.com/gocodebox/lifterlms/issues) and ensure you're not creating a duplicate. If the issue already exists you can add your information to the existing report.

Also check our [known issues and conflicts](https://lifterlms.com/doc-category/lifterlms/known-conflicts/) for possible resolutions.

### Contributing New Features

When contributing new features please communicate with us to ensure this is a feature we're interested in having added to LifterLMS before you start coding it.

First check if we already have a feature request or proposal for the feature you're interested in developing. Take a look at our existing feature requests here in [GitHub](https://github.com/gocodebox/lifterlms/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22type%3A+feature+request%22) and on our [Feature Request voting board](https://trello.com/b/egC72ZZS/lifterlms-road-map-and-feature-voting).

If you can't find an existing feature request you should propose it by opening a new [feature request issue](https://github.com/gocodebox/lifterlms/issues/new?template=Feature_Request.md). In the issue we'll discuss your feature  before you start working on it.

LifterLMS is a project that services a great many users. A feature which is attractive to a small number of users may create confusion for other users. These features may be better offered as a feature plugin instead of code in the core. In this scenario we'd be happy to help advise you on how to best develop and launch your feature as a plugin on WordPress.org! We'll even help market your add-on after you launch.

### Contributing Code

+ Fork the repository on GitHub.
+ [Install LifterLMS for development](../docs/installing.md).
+ Create a new branch from the 'trunk' branch.
+ Make the changes to your forked repository.
+ Ensure you stick to our [coding standards](https://github.com/gocodebox/lifterlms/blob/trunk/docs/coding-standards.md) and have properly documented new and updated functions, methods, actions, and filters following our [documentation standards](https://github.com/gocodebox/lifterlms/blob/trunk/docs/documentation-standards.md).
+ Run PHPCS and ensure the output has no errors. We **will** reject pull requests if they fail codesniffing.
+ Ensure new code doesn't break existing tests and add new code should aim to have 100% code coverage. See the [testing guide](https://github.com/gocodebox/lifterlms/blob/trunk/tests/phpunit/README.md) to get started with testing and let us know if you want help writing tests, we're happy to help!
+ When making changes to (S)CSS and Javascript files, you should only modify the source files. The compiled and minified files *should not be committed* or included in your PR.
+ When committing, reference your issue (if present) and include a note about the fix. Use [GitHub auto-references](https://help.github.com/en/articles/autolinked-references-and-urls).
+ Push the changes to your fork
+ Submit a pull request to the 'dev' branch of the LifterLMS repo.
+ We'll review all pull requests, and make suggestions and changes if necessary. We're newly open source and supporting users and customers and our own internal pull requests and releases will take priority over pull requests from the community. Please be patient!


### Contribute Translations

All translations to LifterLMS can be made via our GlotPress project at [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/lifterlms).

Anyone can contribute translations. All you need is to login to your wordpress.org account. If you have questions about how to submit translations please refer to the [Translator's Handbook](https://make.wordpress.org/polyglots/handbook/).

We're always seeking Translation Editors who can manage and approve translations for their locale. If you're interested in becoming a translation editor for your locale please [review the documentation about translations here](https://lifterlms.com/docs/how-can-i-contribute-translations-to-lifterlms/).


### Need Help Getting Started as a Contributor?

A number of resources are available for first time contributors:

+ Join our [LifterLMS Community Slack Channel](https://lifterlms.com/slack) and hop into the `#developers` channel. Our core contributors and maintainers are there to help out and answer questions.
+ Check out the [LifterLMS Community Events Calendar](https://lifterlms.com/community-events/) for opportunities to interact with other contributors.
+ Check out [this tutorial](https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github) on how to submit pull requests on GitHub.
+ Grab an issue marked tagged as a [`good first issue`](https://github.com/gocodebox/lifterlms/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)


================================================
FILE: .github/ISSUE_TEMPLATE/Bug_Report.md
================================================
---
name: Bug Report
about: Report a bug or issue

---

### Reproduction Steps

+ Include clear and detailed step by step instructions on how the issue can be reliably reproduced
+ Include screenshots where applicable
+ Record a video if possible (if you post a video please still include a text version of your recreation steps!)


### Expected Behavior

+ Include a concise description of what you expected to happen (but didn't)


### Actual Behavior

+ Include a concise description of what actually happens (but isn't supposed to)


### Error Messages / Logs

+ Include any relevant error messages or log files
```
<!-- Paste error logs / backtraces below this line -->

```

### System and Environment Information

<details>
<summary>System Report</summary>

<!-- Paste your System Report between the three backticks below this line -->
```


```

</details>


This issue has be recreated:
+ [ ] Locally
+ [ ] On a staging site
+ [ ] On a production website
+ [ ] With only LifterLMS and a default theme

### Browser, Device, and Operating System Information

+ Browser name and version
+ Operating System name and version
+ Device name and version (if applicable)


================================================
FILE: .github/ISSUE_TEMPLATE/Feature_Request.md
================================================
---
name: Feature request
about: Suggest an idea or new feature for LifterLMS

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.


================================================
FILE: .github/ISSUE_TEMPLATE/Question.md
================================================
---
name: Question
about: Questions or 'how to' about LifterLMS

---

Remember that GitHub is NOT a support form! If you require user support with LifterLMS you will have more success in one of the following places:

- Support Forums: https://wordpress.org/support/plugin/lifterlms
- Official Support Tickets: https://lifterlms.com/my-account/my-tickets
- LifterLMS Community Slack Channel: https://lifterlms.com/slack

You may also wish to peruse our documentation at https://lifterlms.com/docs

If none of these places seem appropriate ask away here.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Contributors:
Prior to opening a pull request, please review our contributing guidelines at https://github.com/gocodebox/lifterlms/blob/trunk/.github/CONTRIBUTING.md
-->

## Description
<!-- Please describe what you have changed or added -->

Fixes #<!-- insert the related issue number here -->

## How has this been tested?
<!-- Please describe in detail how you tested your changes. -->
<!-- Include details of your testing environment, tests ran to see how -->
<!-- your change affects other areas of the code, etc. -->

## Screenshots <!-- if applicable -->

## Types of changes
<!-- What types of changes does your code introduce?  -->
<!-- Bug fix (non-breaking change which fixes an issue) -->
<!-- New feature (non-breaking change which adds functionality) -->
<!-- Breaking change (fix or feature that would cause existing functionality to not work as expected) -->

## Checklist:
- [ ] This PR requires and contains at least one changelog file. <!-- To create a changelog yml file: `npm run dev changelog add -- -i` and follow the prompt. See also: https://github.com/gocodebox/lifterlms/blob/trunk/packages/dev/README.md#changelog-add -->
- [ ] My code has been tested.
- [ ] My code passes all existing automated tests. <!-- Check code: `composer run-script tests-run`, Guidelines: https://github.com/gocodebox/lifterlms/blob/trunk/tests/README.md -->
- [ ] My code follows the LifterLMS Coding & Documentation Standards. <!-- Check code: `composer run-script check-cs-errors`, Guidelines: https://github.com/gocodebox/lifterlms/blob/trunk/docs/coding-standards.md and https://github.com/gocodebox/lifterlms/blob/trunk/docs/documentation-standards.md -->



================================================
FILE: .github/SECURITY.md
================================================
Security Policy
---------------

## Supported Versions

The current minor version (currently LifterLMS 7.8.x) is the only supported branch of LifterLMS. If you're using an unsupported version of LifterLMS we strongly recommend you upgrade to the latest version as soon as possible.

## Reporting a Vulnerability

The LifterLMS team takes security issues and vulnerabilities very seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

To report a vulnerability, please see our guidelines at https://lifterlms.com/security/


================================================
FILE: .github/workflow-matrix.yml
================================================
###
#
# Custom workflow matrix configurations
#
# @link https://github.com/gocodebox/.github/tree/trunk/.github/actions/setup-matrix
#
###
Test PHPUnit:
  __delete:
    # Remove the LLMS Nightly job (intended for add-ons).
    - include[1]


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "CodeQL"

on:
  pull_request:

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        # Override automatic language detection by changing the below list
        # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
        language: ['javascript']
        # Learn more...
        # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        # We must fetch at least the immediate parents so that if this is
        # a pull request then we can checkout the head.
        fetch-depth: 2

    # If this run was triggered by a pull request event, then checkout
    # the head of the pull request instead of the merge commit.
    - run: git checkout HEAD^2
      if: ${{ github.event_name == 'pull_request' }}

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
         languages: ${{ matrix.language }}

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1


================================================
FILE: .github/workflows/contributors.yml
================================================
name: Contributors

on:
  workflow_dispatch:
  push:
    branches:
      - trunk

concurrency:
  group: ${{ github.workflow }}-${{ 'pull_request' == github.event_name && github.head_ref || github.sha }}
  cancel-in-progress: true

jobs:

  build:
    name: Update contributors
    runs-on: ubuntu-latest

    steps:

      - name: Checkout
        uses: actions/checkout@v2
        with:
          token: ${{ secrets.ORG_WORKFLOWS }}

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '16'
          cache: 'npm'

      - name: Install dependencies
        run: npm install contributor-faces

      - name: Update README.md
        run: ./node_modules/.bin/contributor-faces -e '*\[bot\]' -l 100

      - name: Commit Updates
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Update contributors list
          branch: trunk
          file_pattern: README.md
          commit_user_name: contributors-workflow[bot]
          commit_user_email: 41898282+github-actions[bot]@users.noreply.github.com


================================================
FILE: .github/workflows/keep-alive.yml
================================================
###
#
# This workflow file is deployed into this repository via the "Sync Organization Files" workflow.
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/actions/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/keep-alive.yml}
#
# Keep Repo Alive
#
# This workflow ensures that cronjob workflows are not automatically disabled after 60 days of repo inactivity.
# The workflow will automatically add an empty commit if the repo's latest commitwas made more than 50 days ago. This empty commit will prevent GitHub from automatically disabling this (and other)
# cronjob actions in the repo.
#
###
name: Keep Repo Alive

on:
  # Once daily at 00:00 UTC.
  schedule:
    - cron: '0 0 * * *'

jobs:

  keep-alive:
    name: Keep Repo Alive
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.ORG_WORKFLOWS }}
          fetch-depth: 0
      - name: Add keep-alive commit
        run: |
          LAST_COMMIT_TIME=$( git --no-pager log -1 --format=%ct )
          NOW=$( date +%s )
          DIFF_IN_DAYS=$(( ( NOW - LAST_COMMIT_TIME ) / 86400 ))

          echo "Days since last commit: $DIFF_IN_DAYS"

          if (( $DIFF_IN_DAYS > 50 )); then
            echo "Adding a keep-alive commit."
          
            git config --global user.name "keepalive[bot]"
            git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"

            git commit --allow-empty -m "Automated commit from the Keep Repo Alive workflow"
            git push origin HEAD
          else
            echo "No keep-alive commit required."
          fi

================================================
FILE: .github/workflows/lint-js.yml
================================================
###
#
# This workflow file is deployed into this repository via the "Sync Organization Files" workflow
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/actions/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/lint-js.yml}
#
###
name: Lint JavaScript

on:
  workflow_dispatch:
  pull_request:
  # Once daily at 00:00 UTC.
  # schedule:
  #  - cron: '0 0 * * *'

concurrency:
  group: ${{ github.workflow }}-${{ 'pull_request' == github.event_name && github.head_ref || github.sha }}
  cancel-in-progress: true

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Setup Node
      uses: actions/setup-node@v1
      with:
        node-version: '16'
        cache: 'npm'

    - name: Install npm dependencies
      run: npm ci

    - name: Run linter
      continue-on-error: true
      run: npm run lint:js


================================================
FILE: .github/workflows/ossar-analysis.yml
================================================
# This workflow integrates a collection of open source static analysis tools
# with GitHub code scanning. For documentation, or to provide feedback, visit
# https://github.com/github/ossar-action
name: OSSAR

on:
  pull_request:

jobs:
  OSSAR-Scan:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Run OSSAR
      uses: github/ossar-action@v1
      id: ossar
      
    - name: Upload results to Security tab
      uses: github/codeql-action/upload-sarif@v1
      with:
        sarif_file: ${{ steps.ossar.outputs.sarifFile }}


================================================
FILE: .github/workflows/project-automation.yml
================================================
name: Issue & PR Automation

on:
  issues:
    types:
      - opened
      - reopened
  pull_request_target:
    types:
      - opened
      - reopened
      - review_requested

env:
  PRIMARY_CODEOWNER: '@ideadude'
  PROJECT_ORG: gocodebox
  PROJECT_ID: 18

jobs:

  #######################################
  # Add issue to the Development project.
  #######################################
  issue-to-project:
    name: Move Issue to Project Board
    runs-on: ubuntu-latest
    if: ( 'issues' == github.event_name && ( 'opened' == github.event.action || 'reopened' == github.event.action ) )
    steps:
      - name: Add Issue to Project
        uses: leonsteinhaeuser/project-beta-automations@v2.1.0
        with:
          gh_token: ${{ secrets.ORG_WORKFLOWS }}
          organization: ${{ env.PROJECT_ORG }}
          project_id: ${{ env.PROJECT_ID }}
          resource_node_id: ${{ github.event.issue.node_id }}
          status_value: "Awaiting Triage"

      # - uses: hmarr/debug-action@v2

  ####################################
  # Assign to the project's CODEOWNER.
  ####################################
  issue-assig:
    name: Assign Issue to the Primary CODEOWNER
    runs-on: ubuntu-latest
    if: ( 'issues' == github.event_name && ( 'opened' == github.event.action || 'reopened' == github.event.action ) && ( null == github.event.issue.assignee ) )
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        
      - name: Check CODEOWNERS file existence
        id: codeowners_file_exists
        uses: andstor/file-existence-action@v2
        with:
          files: .github/CODEOWNERS

      - name: Parse CODEOWNERS file
        id: codeowner
        if: steps.codeowners_file_exists.outputs.files_exists == 'true'
        uses: SvanBoxel/codeowners-action@v1
        with:
          path: .github/CODEOWNERS
      
      - name: Update PRIMARY_CODEOWNER env var
        if: steps.codeowners_file_exists.outputs.files_exists == 'true'
        run: |
          echo PRIMARY_CODEOWNER=$( echo '${{ steps.codeowner.outputs.codeowners }}' | jq -r '."*"[0]' ) >> $GITHUB_ENV   

      - name: Strip @ from username
        run: |
          echo "PRIMARY_CODEOWNER=${PRIMARY_CODEOWNER#?}" >> $GITHUB_ENV

      - name: Assign issue
        uses: pozil/auto-assign-issue@v1
        with:
          repo-token: ${{ secrets.ORG_WORKFLOWS }}
          assignees: ${{ env.PRIMARY_CODEOWNER }}

  #####################################
  # Add PRs to the Development project.
  #####################################
  pr-to-board:
    name: Move Pull Request to the Project Board
    runs-on: ubuntu-latest
    if: ( 'pull_request_target' == github.event_name && ( 'opened' == github.event.action || 'reopened' == github.event.action || 'review_requested' == github.event.action ) )
    steps:
      - name: Mark PR as Awaiting Review
        uses: leonsteinhaeuser/project-beta-automations@v2.1.0
        with:
          gh_token: ${{ secrets.ORG_WORKFLOWS }}
          organization: ${{ env.PROJECT_ORG }}
          project_id: ${{ env.PROJECT_ID }}
          resource_node_id: ${{ github.event.pull_request.node_id }}
          status_value: "Awaiting Review"


================================================
FILE: .github/workflows/publish.yml
================================================
name: Release Publication and Distribution

on:
  workflow_dispatch:
  push:
    branches:
      - trunk
    paths:
      - 'CHANGELOG.md'

jobs:

  check-secrets:
    name: "Check for required secrets"
    runs-on: ubuntu-latest
    outputs:
      has-secrets: ${{ steps.check-secrets.outputs.has-secrets }}
    steps:
      - name: Test secrets
        id: check-secrets
        run: |
          if [ ! -z "${{ secrets.LLMS_COM_API_URL }}" ] && [ ! -z "${{ secrets.LLMS_COM_API_KEY }}" ]; then
            echo "::set-output name=has-secrets::true"
          fi

  update-metadata:
    name: "Update product metadata at LifterLMS.com"
    runs-on: ubuntu-latest

    needs: check-secrets
    if: ${{ 'true' == needs.check-secrets.outputs.has-secrets }}

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '16'
          cache: 'npm'

      - name: Install Node dependencies
        run: npm i @lifterlms/dev

      - name: Get metadata
        run: |
          __LLMS_METADATA=$( ./node_modules/.bin/llms-dev meta parse -f json )
          echo __LLMS_PKG_VERSION=$( echo $__LLMS_METADATA | jq --raw-output '.["Version"]' ) >> $GITHUB_ENV
          echo __LLMS_WP_VERSION=$( echo $__LLMS_METADATA | jq --raw-output '.["Requires at least"]' ) >> $GITHUB_ENV
          echo __LLMS_PHP_VERSION=$( echo $__LLMS_METADATA | jq --raw-output '.["Requires PHP"]' ) >> $GITHUB_ENV
          echo __LLMS_LLMS_VERSION=$( echo $__LLMS_METADATA | jq --raw-output '.["LLMS Requires at least"]' ) >> $GITHUB_ENV

      - name: Test metadata
        run: |
          echo "Package version: $__LLMS_PKG_VERSION"
          echo "Min WP Version: $__LLMS_WP_VERSION"
          echo "Min PHP Version: $__LLMS_PHP_VERSION"
          echo "Min LLMS Version: $__LLMS_LLMS_VERSION"

      - name: Update metadata
        run: |
          curl --location --request PATCH "${{ secrets.LLMS_COM_API_URL }}v3/products/${{ github.event.repository.name }}" \
          --header "X-API-KEY: ${{ secrets.LLMS_COM_API_KEY }}" \
          --header 'Content-Type: application/x-www-form-urlencoded' \
          --data-urlencode "version=$__LLMS_PKG_VERSION" \
          --data-urlencode "wp_version=$__LLMS_WP_VERSION" \
          --data-urlencode "php_version=$__LLMS_PHP_VERSION" \
          --data-urlencode "llms_version=$__LLMS_LLMS_VERSION"


================================================
FILE: .github/workflows/sync-branches.yml
================================================
###
#
# This workflow file is deployed into this repository via the "Sync Organization Files" workflow
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/actions/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/sync-branches.yml}
#
###
name: Sync Branches
on:
  push:
    branches:
      - trunk
  workflow_dispatch:

jobs:
  sync:
    name: trunk -> dev
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.ORG_WORKFLOWS }}
          fetch-depth: 0
      - name: Perform sync
        run: |
          git config --global user.name "branch-sync[bot]"
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git checkout dev
          git pull origin trunk --no-ff
          git status
          git push origin dev


================================================
FILE: .github/workflows/test-e2e.yml
================================================
###
#
# This workflow file is deployed into this repository via the "Sync Organization Files" workflow
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/actions/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/test-e2e.yml}
#
###
name: Test E2E

on:
  workflow_dispatch:
  pull_request:
  # Once daily at 00:00 UTC.
#  schedule:
#    - cron: '0 0 * * *'

concurrency:
  group: ${{ github.workflow }}-${{ 'pull_request' == github.event_name && github.head_ref || github.sha }}
  cancel-in-progress: true

jobs:
  ###
  #
  # Setup the test matrix.
  #
  ###
  set-matrix:
    name: Setup Matrix
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.setup.outputs.matrix }}
    steps:
      - uses: actions/checkout@v2
      - id: setup
        uses: gocodebox/.github/.github/actions/setup-matrix@trunk

  ###
  #
  # Run tests.
  #
  ###
  test:
    name: "WP ${{ matrix.WP }}"
    needs: set-matrix
    runs-on: ubuntu-latest
    continue-on-error: ${{ matrix.allow-failure }}

    strategy:
      fail-fast: false
      matrix: ${{ fromJSON( needs.set-matrix.outputs.matrix ) }}

    steps:

      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Environment
        uses: gocodebox/.github/.github/actions/setup-e2e@trunk
        with:
          wp-version: ${{ matrix.WP }}
          docker-user: ${{ secrets.DOCKER_USERNAME }}
          docker-pass: ${{ secrets.DOCKER_PASSWORD }}
          node-version: '16'

      # create a folder for the screenshots, this folder will be uploaded as artifact
      - run: mkdir screenshots

      - name: Run test suite
        run: npm run test -- --verbose

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: error-artifacts-wp-${{ matrix.WP }}
          path: |
            tmp/artifacts
            screenshots

  ###
  #
  # Check the status of the entire test matrix.
  #
  # This will succeed if all jobs from the `test` job's matrix succeed. It allows jobs marked with `allow-failure`
  # to fail.
  #
  # This job can be used as a single status check for branch protection rules. Without this
  # we would need to require every job in the above build matrix.
  #
  ###
  status:
    name: Test E2E Status
    runs-on: ubuntu-latest
    if: always()
    needs: test
    steps:
      - name: Check overall matrix status
        if: ${{ 'success' != needs.test.result }}
        run: exit 1


================================================
FILE: .github/workflows/test-js-unit.yml
================================================
name: Test JS Unit

on:
  workflow_dispatch:
  pull_request:
    paths:
        - src/js/**
  # Once daily at 00:00 UTC.
  # schedule:
  #  - cron: '0 0 * * *'

concurrency:
  group: ${{ github.workflow }}-${{ 'pull_request' == github.event_name && github.head_ref || github.sha }}
  cancel-in-progress: true

jobs:
  test:
    name: "Run JS Unit Tests"
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '16'
          cache: 'npm'

      - name: Install Node dependencies
        run: npm ci

      - name: Run test suite
        run: npm run test:unit


================================================
FILE: .github/workflows/test-phpunit.yml
================================================
###
#
# This workflow file is deployed into this repository via the "Sync Organization Files" workflow
#
# Direct edits to this file are at risk of being overwritten by the next sync. All edits should be made
# to the source file.
#
# @see Sync workflow {@link https://github.com/gocodebox/.github/actions/workflows/workflow-sync.yml}
# @see Workflow template {@link https://github.com/gocodebox/.github/blob/trunk/.github/workflow-templates/test-phpunit.yml}
#
###
name: Test PHPUnit

on:
  workflow_dispatch:
    inputs:
      cache-suffix:
        description: Cache suffix
        type: string
  pull_request:
  # Once daily at 01:00 UTC.
  # schedule:
  #  - cron: '0 1 * * *'

concurrency:
  group: ${{ github.workflow }}-${{ 'pull_request' == github.event_name && github.head_ref || github.sha }}
  cancel-in-progress: true

jobs:

  ###
  #
  # Setup the test matrix.
  #
  ###
  set-matrix:
    name: Setup Matrix
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.setup.outputs.matrix }}
    steps:
      - uses: actions/checkout@v2
      - id: setup
        uses: gocodebox/.github/.github/actions/setup-matrix@trunk

  ###
  #
  # Run tests.
  #
  ###
  test:
    name: WP ${{ matrix.WP }} on PHP ${{ matrix.PHP }}${{ matrix.name-append }}

    needs: set-matrix
    runs-on: ubuntu-latest
    continue-on-error: ${{ matrix.allow-failure }}

    strategy:
      fail-fast: false
      matrix: ${{ fromJSON( needs.set-matrix.outputs.matrix ) }}

    steps:

      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Environment
        uses: gocodebox/.github/.github/actions/setup-phpunit@trunk
        with:
          php-version: ${{ matrix.PHP }}
          wp-version: ${{ matrix.WP }}
          llms-branch: ${{ matrix.LLMS }}
          env-file: ".github/.env.test-phpunit"
          deploy-key: ${{ secrets.LLMS_DEPLOY_KEY }}
          secrets: ${{ toJSON( secrets ) }}
          cache-suffix: ${{ inputs.cache-suffix }}

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '16'

      - name: Install NPM Dependencies
        run: npm ci && npm run build

      - name: Run Tests
        run: composer run tests

  ###
  #
  # Check the status of the entire test matrix.
  #
  # This will succeed if all jobs from the `test` job's matrix succeed. It allows jobs marked with `allow-failure`
  # to fail.
  #
  # This job can be used as a single status check for branch protection rules. Without this
  # we would need to require every job in the above build matrix.
  #
  ###
  status:
    name: Test PHPUnit Status
    runs-on: ubuntu-latest
    if: ${{ always() }}
    needs: test
    steps:
      - name: Check overall matrix status
        if: ${{ 'success' != needs.test.result }}
        run: exit 1


================================================
FILE: .gitignore
================================================
# Package managers.
node_modules/
/vendor/

# Lock file intentionally excluded to allow easier testing against multiple php versions
# This follows the precedent put forth by the WordPress core {@link https://github.com/WordPress/wordpress-develop/commit/0e442c4615bdcdc1c2e4f8db6f88f57e6859c2ff}
composer.lock

# Ignore built files
/readme.txt
assets/css/admin.css
assets/css/admin.min.css
assets/css/admin-rtl.css
assets/css/admin-rtl.min.css
assets/css/admin-wizard-rtl.css
assets/css/admin-wizard-rtl.min.css
assets/css/admin-wizard.css
assets/css/admin-wizard.min.css
assets/css/builder.css
assets/css/builder.min.css
assets/css/builder-rtl.css
assets/css/builder-rtl.min.css
assets/css/bricks-editor-rtl.css
assets/css/admin-importer*
assets/css/editor*
assets/css/certificates*
assets/css/lifterlms-rtl.css
assets/css/lifterlms-rtl.min.css
assets/css/lifterlms.css
assets/css/lifterlms.min.css
assets/css/llms-admin-addons.css
assets/css/llms-admin-addons-rtl.css
assets/css/llms-focus-mode*

assets/js/llms-builder.js
assets/js/llms-builder.min.js
assets/js/llms-admin-elementor-editor.js
assets/js/llms-admin-elementor-editor.asset.php
assets/js/llms-admin-certificate-editor.asset.php
assets/js/llms-admin-certificate-editor.js
assets/js/llms-admin-media-protection-block-protect.asset.php
assets/js/llms-admin-media-protection-block-protect.js
assets/js/llms-components.asset.php
assets/js/llms-components.js
assets/js/llms-admin-addons.js
assets/js/llms-admin-award-certificate.js
assets/js/llms-icons.js
assets/js/llms-quill-wordcount.js
assets/js/llms-spinner.js
assets/js/llms-utils.js
assets/js/llms.js
assets/js/*.min.js
assets/js/*.asset.php
assets/js/llms-metaboxes.js
blocks/certificate-title/*
blocks/my-account/*
blocks/pricing-table/*
blocks/access-plan-button/*
blocks/checkout/*
blocks/course-author/*
blocks/course-continue/*
blocks/course-meta-info/*
blocks/course-outline/*
blocks/course-prerequisites/*
blocks/course-reviews/*
blocks/course-syllabus/*
blocks/courses/*
blocks/login/*
blocks/memberships/*
blocks/my-achievements/*
blocks/navigation-link/*
blocks/registration/*

includes/class.llms.l10n.frontend.php
languages/lifterlms.pot

# Ignore composer-installed libs.
/libraries/*
!/libraries/index.php
!/libraries/README.md

# Exclude maps.
/blocks/**/*.js.map
/assets/css/*.map
/assets/js/*.map
/assets/maps/*

# Misc.
*.log
.DS_Store

# Release distribution directory.
/dist/
/tmp/

# Non-distributable configs.
phpunit.xml
.llmsenv


================================================
FILE: .llmsconfig
================================================
{
	"build": {
		"custom": [ "js-additional", "js-builder" ]
	},
	"docs": {
		"package": "LifterLMS"
	},
	"pot": {
		"bugReport": "https://github.com/gocodebox/lifterlms/issues",
		"domain": "lifterlms",
		"dest": "languages/",
		"jsClassname": "LLMS_L10n_JS",
		"jsFilename": "class.llms.l10n.frontend.php",
		"jsSince": "3.17.8",
		"jsSrc": [ "assets/js/**/*.js", "!assets/js/**/*.min.js", "!assets/js/**/*.js.map" ],
		"lastTranslator": "Thomas Patrick Levy <help@lifterlms.com>",
		"team": "LifterLMS <help@lifterlms.com>",
		"package": "lifterlms",
		"phpSrc": [
			"./*.php", "./**/*.php",
			"!vendor/*", "!vendor/**/*.php", "!tmp/**", "!tests/**", "!wordpress/**",
			"./vendor/lifterlms/lifterlms-blocks/*.php", "./vendor/lifterlms/lifterlms-blocks/**/*.php",
			"./vendor/lifterlms/lifterlms-rest/*.php", "./vendor/lifterlms/lifterlms-rest/**/*.php"
		]
	},
	"publish": {
		"title": "LifterLMS",
		"lifterlms": {
			"make": {
				"tags": [ 6 ]
			},
			"pot": false
		}
	},
	"scripts": {
		"src": [
			"assets/js/**/*.js",
			"!assets/js/llms-admin-addons.js",
			"!assets/js/llms-admin-award-certificate.js",
			"!assets/js/llms-admin-certificate-editor.js",
			"!assets/js/llms-admin-media-protection-block-protect.js",

			"!assets/js/**/*.min.js",
			"!assets/js/llms-builder*.js",
			"!assets/js/app/**/*.js",
			"!assets/js/builder/**/*.js",
			"!assets/js/partials/**/*.js",
			"!assets/js/private/**/*.js",


			"!assets/js/llms-components.js",
			"!assets/js/llms-icons.js",
			"!assets/js/llms-quill-wordcount.js",
			"!assets/js/llms-spinner.js",
			"!assets/js/llms-utils.js"
		],
		"dest": "assets/js/"
	},
	"watch": {
		"custom": [ {
			"glob": [ "assets/js/builder/**/*.js", "assets/js/private/**/*.js", "assets/js/app/*.js" ],
			"tasks": [ "js-additional", "js-builder" ]
		} ]
	},
	"zip": {
		"composer": true,
		"src": {
			"custom": [
				"!./**/CHANGELOG.md",
				"!./**/README.md",
				"!./_private/**",
				"!./_readme/**",
				"!./docs/**",
				"!./packages/**",
				"!./wordpress/**",
				"!lerna.json",
				"!babel.config.js",
				"!docker-compose.override.yml.template"
			]
		}
	}
}


================================================
FILE: .llmsdev.yml
================================================
pot:
  dir: languages


================================================
FILE: .llmsdevrc
================================================
{
	"readme": {
		"title": "LMS by LifterLMS - Online Course, Membership & Learning Management System Plugin for WordPress",
		"shortDescription": "LifterLMS is a powerful WordPress learning management system plugin that makes it easy to create, sell, and protect engaging online courses and training based membership websites.",
		"meta": {
			"Tags": "learning management system, LMS, membership, elearning, online courses, quizzes, sell courses, badges, gamification, learning, Lifter, LifterLMS",
			"Requires at least": "5.4",
			"Tested up to": "5.8",
			"Requires PHP": "7.3"
		},
		"changelog": {
			"link": "https://make.lifterlms.com/tag/lifterlms/"
		},
		"sections": {
			"Description": "file:./.wordpress-org/readme/description.md",
			"Installation": "file:./.wordpress-org/readme/installation.md",
			"Frequently Asked Questions": "file:./.wordpress-org/readme/faqs.md",
			"Screenshots": "file:./.wordpress-org/readme/screenshots.md"
		}
	},
	"i18n": {
		"dir": "./languages/"
	}
}


================================================
FILE: .llmsenv.dist
================================================
WORDPRESS_PORT=8080
WORDPRESS_TITLE=LifterLMS Core e2e


================================================
FILE: .source/README.md
================================================
LifterLMS Source Images
=======================

This directory contains source images (.svg, .ai, .psd, etc...) for any image assets used in the LifterLMS core.


================================================
FILE: .wordpress-org/README.md
================================================
WordPress.org Plugin Repository Content and Assets
==================================================

This directory contains the text content and assets used on the LifterLMS plugin listing on [WordPress.org Plugin Repository](https://wordpress.org/plugins/lifterlms/). 

## README

The [readme](./readme) directory contains the markdown files representing the sections (and tabs) used on the listing.

These files are combined during a build step prior distribution and output as the [readme.txt](../readme.txt) file distributed with the LifterLMS plugin. Generally we do not ship updates for changes to the readme directory. These changes will be included in the next release which contains code changes.

The files are prepended with numbers to preserve their order when programmatically combined.

The command to build the readme file is `npm run dev readme`. See full documentation of the command in the [@lifterlms/dev package reference](https://github.com/gocodebox/lifterlms/tree/trunk/packages/dev#readme).

### File Parts

+ [01-header.md](./readme/01-header.md): The readme header containing the listing's display title, meta data, and a short description.
+ [05-description.md](./readme/05-description.md): The main listing "Details" tab.
+ [10-installation.md](./readme/10-installation.md): The contents of the "Installation" tab
+ [15-faqs.md](./readme/15-faqs.md): A list of frequently asked questions. This is listed at the bottom of the "Details" tab on the listing page.
+ [20-screenshots.md](./readme/15-faqs.md): An ordered list of screenshot captions. Each caption should correspond with a screenshot in the [assets directory](./assets). A screenshot with the filename `screenshot-5.png` corresponds to the item 5 in the screenshot list. 
+ [25-changelog.md](./readme/25-changelog.md): an auto-generated changelog containing the latest 10 changelog entries from the main [CHANGELOG.md](../CHANGELOG.md) file.

### Merge Codes

Various merge codes are available for use in the readme file parts. See the [@lifterlms/dev package reference](https://github.com/gocodebox/lifterlms/tree/trunk/packages/dev#readme) for merge code documentation.

## Assets

The [assets](./assets) directory contains the images used in the listing: banners, icons, and screenshots.

See also: [How Your Plugin Assets Work](https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/).

Assets are manually synced to WordPress.org via SVN @thomasplevy and will be updated in conjunction with the next release following their update in this directory.

================================================
FILE: .wordpress-org/readme/01-header.md
================================================
=== LifterLMS - WP LMS for eLearning, Online Courses, & Quizzes ===
Contributors: lifterlms, chrisbadgett, strangerstudios, kimannwall, d4z_c0nf, actuallyakash, codeboxllc, brianhogg
Donate link: {{__PROJECT_URI__}}
Tags: lms, course, elearning, learning management system, quiz
License: {{__LICENSE__}}
License URI: {{__LICENSE_URI__}}
Requires at least: {{__MIN_WP_VERSION__}}
Tested up to: {{__TESTED_WP_VERSION__}}
Requires PHP: {{__MIN_PHP_VERSION__}}
Stable tag: {{__VERSION__}}

{{__SHORT_DESCRIPTION__}}


================================================
FILE: .wordpress-org/readme/05-description.md
================================================
== Description ==
LifterLMS is a secure easy-to-use WordPress LMS plugin packed with features to easily create & sell courses online.

Turn your WordPress website into a professional eLearning platform with every customizable feature you could possibly need from your LMS.

+ **Intuitive LMS Course Builder:** Create Courses, Sections, and Interactive Lessons with multimedia content.
+ **Track Student Progress:** In-Depth Reporting, Create Timed or Open Quizzes, Drip Content, Add Prerequisites, Analyze Progress, and Award Certificates
+ **Complete Ecommerce Platform:** Built-in Gateway Integration for Stripe and PayPal With Memberships and Subscriptions 
+ **Community and Social Learning:** Integrate a Community Forum or Discussion Area, Add Multiple Instructors, and Display Course Reviews

[Explore All LMS Features](https://lifterlms.com/features/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)

LifterLMS makes it easy to create, sell, and protect engaging online courses and training-based membership websites.

https://www.youtube.com/watch?v=N72Zw2EBm4A

### Integrate LifterLMS With Any Theme, Page Builder, & Block Editor

LifterLMS works with any modern WordPress theme/FSE, the Block Editor (Gutenberg), and every popular WordPress page builder including Elementor, Beaver Builder, and Divi.

**With over 10 years development,** our team is deeply engaged with the WordPress community. We encourage our integration partners to create the extensions you need most, like Affiliate WP, Monster Insights, WP Fusion, popular form plugins, GamiPress, Astra Pro, and more.


### Open Source, Free Core Plugin

LifterLMS gives back to the open-source community. The core LifterLMS plugin is a totally FREE forever LMS - no limits on your courses, memberships, enrollments, or earnings.

We believe in free, distributed learning for all. **LifterLMS exists to democratize education in the digital classroom.**

### Premium Add-ons and Bundles

Get to know our team and product. by signing up for a **[$1 temporary _30 Day_ website](https://lifterlms.com/try/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)**. You'll get instant access to a private demo site hosted on our servers pre-installed with:

+ the core LifterLMS plugin, AND
+ every premium LMS add-on

See why so many people start with or switch from another WordPress LMS or hosted platform to [LifterLMS](https://lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) for online courses, membership sites, and remote schools.

https://www.youtube.com/watch?v=RnZflrWG5YQ

### LifterLMS is Perfect For:

**Builders**
We’re the favorite LMS plugin for WordPress developers, designers and IT pros who **build LMS websites and training portals** for clients, employers, and themselves

**DIY**
Do-it-yourself innovators love that LifterLMS helps them easily **create high-value online courses, coaching or training-based membership websites,** right on WordPress.

**Switchers**
Have you outgrown a hosted LMS platform or an incomplete WordPress LMS stack? Choose LifterLMS if you are looking for **more power, control, and better support**.

### Meet The LifterLMS Team


The LifterLMS team is a **diverse group of talented course creators, developers, designers, marketers, and entrepreneurs**.

Before developing LifterLMS, we consulted and built custom WordPress-based online learning and membership sites for clients worldwide. LifterLMS was born through this deep hands-on experience building high-end, custom WordPress LMS websites from scratch.

Learn more about [the people behind LifterLMS](https://lifterlms.com/about-us/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale#h-meet-the-team).

### LifterLMS By The Numbers

+ 8,377,042 Course Enrollments powered by LifterLMS
+ 12,570,881 Course and lesson completions powered by LifterLMS
+ 186,997 Achievement badges awarded by LifterLMS
+ 310,728 Certificates awarded by LifterLMS
+ Over 10,000 active installs of the WordPress LMS plugin
+ [308 5-star reviews](https://wordpress.org/support/plugin/lifterlms/reviews/?filter=5)

### [Features](https://lifterlms.com/features/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)

Start with the free LMS plugin and [scale-up](https://lifterlms.com/pricing/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale) as you grow.

https://www.youtube.com/watch?v=ZNwo5inRSdM

**Make Money Teaching Online**
Set up LifterLMS, activate built-in payments with [Stripe](https://lifterlms.com/product/stripe-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) or [PayPal](https://lifterlms.com/product/paypal-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale). That's all you need to get started.

When you need more features and to expand your online learning business, we're here for you. We have several free and premium add-ons to help you create more value for your users, and scale your business revenue.

+ Credit card payments
+ One-time payments
+ Recurring payments
+ Payment plans
+ Unlimited course and membership pricing models
+ PayPal
+ Subscriptions
+ Checkout
+ Free courses
+ Course bundles
+ Private coaching upsells
+ Course and membership Coupons
+ Bulk course and membership sales
+ Affiliate ready
+ Native course and membership sales pages
+ Offline course and membership sales
+ Customizable course and membership enrollment
+ Country and currency
+ E-commerce dashboard
+ Credit card management
+ Subscription switching
+ Payment switching
+ Native Zapier integration

**Create Courses on Your WordPress LMS Website**


+ Course multimedia lessons
+ Course quizzes
+ Quiz question banks
+ Course builder
+ Course cohorts
+ Drip Content
+ Course and lesson prerequisites
+ Course tracks
+ Course assignments
+ Quiz time limits
+ Student dashboard
+ Student note-taking
+ Multi-instructor courses
+ Lesson downloads
+ Course import & export
+ Discussion areas
+ Instructional design
+ Forum integrations
+ Graphics pack
+ Course reviews
+ Group enrollments for courses and memberships

**Engage Your Students**


+ Achievement badges
+ Certificates
+ Personalized email
+ Social learning
+ Private coaching
+ Text messaging

**Offer Memberships**

+ Sitewide membership
+ Course bundles
+ Traditional memberships
+ Automatic course enrollment
+ Bulk course enrollment
+ Content restrictions outside of a course
+ Members-only payment plans
+ Private group discussions
+ Members-only forums

**Integrate your WordPress LMS with the Tools You Need**

+ Payment gateways
+ Email marketing
+ Forums
+ Mobile friendly
+ Use any theme or page builder
+ Built for compatibility
+ CRMs
+ E-learning authoring tools
+ Tin Can API (xAPI)

**Secure and Protect Your Content**

+ Course protection
+ User account management and registration
+ Members only content
+ Course only content
+ Restricted access
+ Password management
+ Self-hosted

**Own and Manage Your WordPress LMS Platform**

+ Detailed course, membership, ecommerce, and student reporting
+ Course gradebook
+ Email notifications
+ Bulk course and membership enrollments
+ Student management
+ Course and membership access management
+ Web design management
+ Branding & typography
+ WordPress LMS User Roles
+ Security
+ Require terms
+ Scalable
+ Layout
+ Testing tools

**Get Support For Your WordPress LMS Project**

+ Technical support
+ 30 Days of live weekly onboarding calls called [Liftoff Sessions](https://lifterlms.com/blog/liftoff/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ [Live office hours](https://lifterlms.com/product/office-hours/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [Free training courses](https://academy.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ [Free training webinars](https://lifterlms.com/lifterlms-webinars/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ Setup wizard
+ [Detailed documentation](https://lifterlms.com/docs/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ Dynamic resources
+ Demo course
+ System analyzer
+ User community
+ [REST API](https://developer.lifterlms.com/rest-api/)
+ [Developer ecosystem](https://make.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ [Recommended Resources](https://lifterlms.com/recommended-resources/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale) for course creators

**More Resources**

+ The [LifterLMS Official Homepage](https://lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ The [LifterLMS Knowledge base](https://lifterlms.com/docs/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ The [LifterLMS Blog](https://lifterlms.com/blog/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ The [LifterLMS Podcast](https://podcast.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ The [LifterLMS Academy](https://academy.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ The [LifterLMS Developer Blog](https://make.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)


### Enhance Your LMS With LifterLMS Add-Ons

**Advanced**

Increase your LMS website and it's training program's value with these add-ons:

+ [LifterLMS Advanced Quizzes](https://lifterlms.com/product/advanced-quizzes//?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Assignments](https://lifterlms.com/product/lifterlms-assignments/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Private Areas](https://lifterlms.com/product/private-areas/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Social Learning](https://lifterlms.com/product/social-learning/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Advanced Video](https://lifterlms.com/product/advanced-video/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Custom Fields](https://lifterlms.com/product/custom-fields/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Groups](https://lifterlms.com/product/groups/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS PDFs](https://lifterlms.com/product/lifterlms-pdfs/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Private Site](https://lifterlms.com/product/private-site/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Course Cohorts](https://lifterlms.com/product/course-cohorts/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Advanced Coupons](https://lifterlms.com/product/lifterlms-advanced-coupons/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Notes](https://lifterlms.com/product/lifterlms-notes/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Continuing Education](https://lifterlms.com/product/lifterlms-continuing-education/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Gifts](https://lifterlms.com/product/lifterlms-gifts/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)

**Integrations**

Integrate your LMS with the tools you use:

+ [LifterLMS Stripe](https://lifterlms.com/product/stripe-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS PayPal](https://lifterlms.com/product/paypal-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Authorize.Net](https://lifterlms.com/product/authorize-net/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS WooCommerce](https://lifterlms.com/product/woocommerce-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Kit](https://lifterlms.com/product/lifterlms-convertkit/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Mailchimp](https://lifterlms.com/product/mailchimp-extension/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)

### LMS Website and User Experience Design Tools

Use LifterLMS with the modern LifterLMS [Sky Pilot Theme](https://lifterlms.com/product/sky-pilot/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) for even more beautiful results. LifterLMS works with any well-coded WordPress theme, but check out [Sky Pilot](https://lifterlms.com/product/sky-pilot/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) if you want to start with a modern, beautiful, full-site editing block-based theme. And consider using our [Aircraft page builder plugin](https://lifterlms.com/product/aircraft/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale), to make building beautiful web pages fast using our design template library.

+ [LifterLMS Sky Pilot Theme](https://lifterlms.com/product/sky-pilot/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Aircraft](https://lifterlms.com/product/aircraft/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)
+ [LifterLMS Powerpack](https://lifterlms.com/product/lifterlms-pro/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)

https://www.youtube.com/watch?v=tE1K1FHiYDM

### Why Do People Switch to LifterLMS From Other LMS Plugins?

There are several other LMS plugins like:

+ Sensei LMS
+ Tutor LMS
+ WP Courseware
+ LearnDash
+ Masterstudy LMS
+ Academy LMS
+ Namaste LMS
+ LearnPress

There are some membership plugins with some course features like:

+ Paid Memberships Pro (Membership plugin that also integrates with LifterLMS)
+ MemberPress

The main reasons we hear from users who switched to LifterLMS after trying out the [best WordPress LMS plugins](https://lifterlms.com/blog/best-wordpress-lms-plugins/) is that LifterLMS has:

+ The best most feature-complete customizable well-coded features
+ Outstanding customer support including live calls
+ The free LifterLMS plugin is amazing making the project affordable
+ Memberships, ecommerce, and gamification included in LifterLMS without the need for 3rd party plugins

### Other Plugins and Themes Commonly Used with LifterLMS

The most common plugins and themes used with LifterLMS include Elementor, WooCommerce, Contact Form 7, Yoast SEO, WP Forms Lite, Akismet Anti-Spam, Elementor, Jetpack by WordPress.com, Classic Editor, Updrafts Plus Backup/Restore, Realy Simple SSL, All-in-One WP Migration, WordPress Importer, Starter Templates, Wordfence Security, Google Analytics for WordPress by MonsterInsights, Loco Translate, Slider Revolution, Astra Pro, Essential Addons for Elementor, WP Mail SMTP, WooCommerce Stripe Gateway, LiteSpeed Cache, Jetpack, Gravity Forms, MailChimp for WooCommerce, BuddyPress, BuddyBoss, Divi, Kadnece, Beaver Builder, bbpress, The Events Calendar, Ultmate Member, and more.

Connect LifterLMS to over 7,000 other apps like Facebook, Google Sheets, Zoom, Shopify, etc. using the [LifterLMS Zapier app](https://lifterlms.com/blog/zapier/).


### Support From LifterLMS

**All of our paid products include priority private support.

+ LifterLMS Support Ticket System, ready for any question you have about your LMS
+ Liftoff Sessions access with live screen-sharing to help you get started with the LMS software
+ [LifterLMS Office Hours](https://lifterlms.com/product/office-hours/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) is a weekly Mastermind group hosted by LifterLMS CEO Chris Badgett and special guests

### Save on LifterLMS With A Bundle

Save money and get more features.

+ [Earth Bundle](https://lifterlms.com/product/earth-bundle/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) gives you all the essentials you need to get your online learning website up and running so it's collecting money today with the most powerful secure learning management system software.
+ Level up your online course LMS website with our ecommerce, design, marketing technology, and automation tools with the [Universe Bundle](https://lifterlms.com/product/universe-bundle/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).
+ Add more engagement and student transformation potential to your immersive training programs with our entire suite of products including advanced features used by the best teachers, experts, and coaches with the [Infinity Bundle](https://lifterlms.com/product/infinity-bundle/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).

### Try the Best LMS Plugin

+ Install the free core LifterLMS plugin right now. See how extensive and customizable our free core plugin is.

+ Get a temporary _30 Day_ website on our servers with the core LifterLMS plugin AND all the premium add-ons installed. This demo website allows you to test drive all the LMS add-ons before you invest. Practice creating courses, test out the learner experience, and see how easy it will be to manage your course with WordPress. Install your favorite plugins & themes to test compatibility. **[Try LifterLMS for $1](https://lifterlms.com/try/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)** now.
+ Test LifterLMS as a student. Take a **free** course on how to build a LifterLMS website in 20 minutes. [Take a Free Course](https://academy.lifterlms.com/course/how-to-build-a-learning-management-system-with-lifterlms/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) now.

### Scaling LifterLMS

LifterLMS is incredibly flexible, customizable, and scalable. Use it for a simple one course website. Use it as a course marketplace or multi-instructor online school.

LifterLMS is lightweight enough to handle small niche sites, while also powering huge universities and employee training in Fortune 500 corporations. We've even worked with a site that has 4,470,829 course enrollments.

Unlike hosted LMS software where you would pay increasing monthly fees for access and growth, LifterLMS does not charge you more per course, per instructor, per student, or based on your revenue.

Whether you are going big or keeping it small, LifterLMS scales to meet your needs.

### LifterLMS in Action
+ [Success Stories](https://lifterlms.com/success/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale) — Discover these amazing stories and accomplishments from our community of course creators.
+ [Showcase](https://lifterlms.com/showcase/?utm_source=LifterLMS%20Plugin&utm_medium=Readme&utm_campaign=Readme%20to%20Sale) — Check out these websites using LifterLMS

### What Others Are Saying About LifterLMS

> _"I've used many LMS platforms over the years. And they were all fine… right up to the day when they weren't. The trouble is, they all want you to package and manage your course the way THEY think you should do it. THEIR feature set. THEIR way to do it. **Now I host all my courses on LifterLMS. TOTALLY different experience. I'm free to do things MY way. I've never yet hit a wall where LifterLMS didn't enable me to do things the way I wanted.** Love it! Great support and community too."_

> _**Nick Usborne**, Teacher, Entrepreneur_

***

> _"As a former School Teacher, professional User Experience Designer, and current online course creator – I can honestly attribute much of our success to LifterLMS and it’s consideration for multiple learning modalities, the LMS UI/UX out of the box, and natural student Engagement opportunities. **In less than 10 months we’ve gone from $0 to $300K in revenue with LifterLMS** playing a huge part in that!!"_

> _**Sarah Lorenzen**, Teacher, Entrepreneur_

***


### Join Our Growing Community

When you download LifterLMS, you **join a thriving community** of education entrepreneurs, course creators, developers, LMS professionals, and WordPress enthusiasts.

We’re a fast growing open source eLearning community, and everyone seeking to build a sustainable online course business is welcome.

Join the [LifterLMS VIP Facebook group](https://www.facebook.com/groups/lifterlmsvip/) to:

+ check out what other LifterLMS users are creating
+ ask questions and support fellow course creators

Join the [LifterLMS Slack community](https://join.slack.com/t/lifterlms/shared_invite/enQtMzk3ODczNjc4Mjc3LTBlMmEzMWYyOTIwMDU3NDc2MmRhNGIxNGE0Nzc1OWIxZjg1OGVhM2E5YTkwYzZmMmM1ZTU4MDQxYjVlZDYyZTE) if you’d prefer to connect in Slack.

### Contribute

Are you a developer interested in contributing to LifterLMS? Visit the [LifterLMS GitHub Repository](https://github.com/gocodebox/lifterlms/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) to find out how to support this open source WordPress LMS software.

Want to add a new language to LifterLMS? Contribute language translations at [translate.wordpress.org](https://translate.lifterlms.com/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


### What Should You Do Next?

** Install the free LifterLMS plugin on your website **,

then ...

**[Try out all the premium add-ons for $1 by signing up >>HERE<<](https://lifterlms.com/try/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)**

🚀

<!-- Test Auto deployment -->



================================================
FILE: .wordpress-org/readme/10-installation.md
================================================
== Installation ==

#### Minimum System Requirements

LifterLMS Requires

+ PHP 7.4 or later
+ WordPress 5.6 or later
+ MySQL 5.6 or later

Visit our [full system requirements](https://lifterlms.com/docs/minimum-system-requirements-lifterlms/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) for additional information.

#### Automatic Installation

The simplest way to install LifterLMS is through your existing WordPress site’s admin. Let WordPress handle file transfers for you - you’ll never need to leave the web browser or admin panel.

1. Log in to your WordPress dashboard
2. Navigate to Plugins -> Add New
3. In the search field, type "LifterLMS" and click "Search Plugins"
4. Once you've located LifterLMS, click "Install Now"
5. Once installation is complete, click "Activate"

#### Manual Installation

To manually install LifterLMS, you'll need to download the zip file using the "Download" link on this screen. Then, use FTP to manually upload the unzipped plugin folder to the proper plugins directory on your webserver.

Please see this [WordPress Codex document](https://wordpress.org/documentation/article/manage-plugins/#manual-plugin-installation-1) for full instructions on Manual Plugin Installation.

#### Setup Wizard

After installation, LifterLMS launches a friendly (and super quick) Setup Wizard.

This wizard helps you configure LifterLMS so you can get to the fun stuff - like creating your courses - as quickly as possible.

The wizard includes a few sample courses you can import if you want to see some examples before you start creating your own content.

You can return to the setup wizard at any time by following [these steps](https://lifterlms.com/docs/rerun-lifterlms-setup-wizard/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


================================================
FILE: .wordpress-org/readme/15-faqs.md
================================================
== Frequently Asked Questions ==

#### Where do I buy add-ons or bundles for my LifterLMS eLearning Website?

You can explore the individual learning management system add-ons [here](https://lifterlms.com/store/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) or save BIG with a [bundle](https://lifterlms.com/product-category/bundles/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)


#### How do I troubleshoot issues with my LMS website?

First, make sure that you're running the latest version of LifterLMS. And if you've got any other LifterLMS plugins active on your site, make sure those are running the most current version as well.

The most common issues we see are either plugin conflicts, theme conflicts, or outdated servers. You can test if a plugin or theme is conflicting by manually deactivating other plugins until just LifterLMS is running on your site. If the issue persists from there, revert to the default Twenty Fifteen theme. If the issue is resolved after deactivating a specific plugin or your theme, you'll know that is the source of the conflict. If it is a hosting issue, contact your web host and make sure they’re running the most current version of PHP.

Also be sure to check out the official LifterLMS [Knowledge Base](https://lifterlms.com/docs/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


#### How do I ask a question about my online course website?

Users of the free LifterLMS should post their questions here in our WordPress.org support area. If you find you're not getting support in as timely a fashion as you wish, you might want to consider [purchasing a product from LifterLMS](https://lifterlms.com/pricing/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale) so you can access the LifterLMS support team.

If you're already a LifterLMS customer, you can simply log into your account and contact the support team directly on the [LifterLMS website](https://lifterlms.com/my-account/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale). We can provide a deeper level of support in there and address your needs on a daily basis during the work week. Generally, except in times of increased support loads, we reply to all comments within 12 business hours.


#### LifterLMS is awesome! Can you set up my online course site for me?

LifterLMS offers technical support, but we do not offer custom website development services. However, we do recommend third party LifterLMS Experts who can help with web design, web development, instructional design or marketing for a fee.  Click here to visit the [LifterLMS Experts page](https://lifterlms.com/experts/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


#### I'm interested in purchasing add-ons for my WordPress LMS website, but I have a few questions first.

If you're not finding your questions answered here or on our website, you can ask your presales questions through this [contact form](https://lifterlms.com/contact/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale). You can also connect live with a member of our team [here](https://lifterlms.com/contact/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


#### What add-ons are available for LifterLMS, and where can I read more about them?

You can find a full list of official LifterLMS Add-ons [here](https://lifterlms.com/store/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)


#### I have a feature idea. What's the best way to tell you about it?

We care about your feature ideas and what you have to say. You can [request a feature](https://lifterlms.com/contact/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale), [vote on existing feature requests](?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale), and checkout the [product roadmap](https://lifterlms.com/roadmap/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale).


#### Do you have any training for building an online course website?

Be sure you’ve taken the free tutorial training video course: [How to Create an Online Course with LifterLMS](https://academy.lifterlms.com/course/how-to-build-a-learning-management-system-with-lifterlms/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale). We also encourage you to get to know us by signing up for a $1 temporary _30 Day_ website on our servers which comes with the core LifterLMS plugin all our add-ons intalled. This demo allows you to test drive all the add-ons before you invest. Check it out here: **[Try LifterLMS for $1](https://lifterlms.com/try/?utm_source=LifterLMS%20Plugin&utm_medium=README&utm_campaign=Readme%20to%20Sale)**.


#### I'm interested in contributing to LifterLMS, how can I start?

LifterLMS is an open source project. We manage our team, developers, issues, and code on [GitHub](https://github.com/gocodebox/lifterlms/).

We welcome contributions of all kinds, anyone can contribute even if you don't write code! Check out our [Contributor's Guidelines](https://github.com/gocodebox/lifterlms/blob/master/.github/CONTRIBUTING.md) to get started.


#### I found a security vulnerability or issue, how can I report it to the team?

The LifterLMS team takes security issues and vulnerabilities very seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

Please contact team@lifterlms.com to report a security vulnerability.

You can review our full security policy at [https://lifterlms.com/security-policy](https://lifterlms.com/security-policy).


================================================
FILE: .wordpress-org/readme/20-screenshots.md
================================================
== Screenshots ==

1. Infinitely customizable course catalog layouts: shown with course title, featured image, and instructor information.
2. View a single course with customizable content including access plans, difficulty, instructor, and lesson syllabus.
3. Edit courses in the WordPress block editor to add pricing tables, progress, outline, and more content.
4. Use the interactive Course Builder to structure your course, sections, lessons, quizzes, assignments and more.
5. Dashboard for course creators in the WordPress admin: an overview of recent statistics and quick links to common admin screens.
6. Advanced reporting for every learner so admins can track an individual students's course progress, membership, engagements, and achievements.
7. Clean and organized plugin settings to help you quickly and easily set up your course or membership site. 
8. Detailed sales and enrollment reporting with built-in time periods or custom fields to filter by term, student, course, and membership.
9. Setup Wizard to help you install and configure your new online course website with LifterLMS in 5 simple steps.

================================================
FILE: .wordpress-org/readme/25-changelog.md
================================================
== Changelog ==

{{__CHANGELOG_ENTRIES__}}


[Read the full changelog]({{__READ_MORE_LINK__}})


================================================
FILE: CHANGELOG.md
================================================
LifterLMS Changelog
===================

v10.0.0 - 2026-05-01
--------------------

##### New Features

+ Lesson content can be edited within the Course Builder for new lessons, or existing lessons with no existing content.
+ Adding tab for Events.
+ Added an explicit 'Any' trigger option for engagements so one engagement can apply to all matching courses, memberships, lessons, quizzes, sections, access plans, or tracks. [#3109](https://github.com/gocodebox/lifterlms/issues/3109)
+ Adding new "focus mode" when viewing lessons and quizzes in a course.
+ Added [lifterlms_lesson_navigation] shortcode.

##### Updates and Enhancements

+ Adding order note when changing the access expiration date.
+ Add additional check for course capacity on the checkout page. [#3086](https://github.com/gocodebox/lifterlms/issues/3086)
+ Allow admin to mark lesson complete with unpublished quiz. [#3127](https://github.com/gocodebox/lifterlms/issues/3127)
+ Scroll to the top of the quiz UI area when a quiz question is loaded.
+ Various course builder fixes, with quizzes set to published by default. [#3033](https://github.com/gocodebox/lifterlms/issues/3033), [#3056](https://github.com/gocodebox/lifterlms/issues/3056), [#3097](https://github.com/gocodebox/lifterlms/issues/3097), [#2938](https://github.com/gocodebox/lifterlms/issues/2938), [#3030](https://github.com/gocodebox/lifterlms/issues/3030)
+ Using standard WP nonce check functions instead of llms_verify_nonce.
+ Removing use of SQL_CALC_FOUND_ROWS due to depreciation in MySQL and observed unreliability of count results.
+ Updating helper and rest libraries, which switch to using standard WP nonce check functions.

##### Bug Fixes

+ Show "Mark Complete" button when quiz requirements are already met. Thanks [@faisalahammad](https://github.com/faisalahammad)! [#3058](https://github.com/gocodebox/lifterlms/issues/3058)
+ Strip formatting when pasting into Course Builder title fields. Thanks [@faisalahammad](https://github.com/faisalahammad)! [#3057](https://github.com/gocodebox/lifterlms/issues/3057)
+ Avoid "block not found" error in the theme template editor.
+ Avoid error protecting media image when multiple thumbnail of same size exist, or registered thumbnail size is missing. [#3129](https://github.com/gocodebox/lifterlms/issues/3129)
+ Close lesson settings panel when lesson has been trashed.
+ Fix lifterlms_loop_columns filter styling to change the number of columns in a loop (ie. Course Catalog). [#3101](https://github.com/gocodebox/lifterlms/issues/3101)
+ Fix pagination for My Courses when using Plain style permalinks. [#3134](https://github.com/gocodebox/lifterlms/issues/3134)
+ Avoids PHP warning for passing null to exit() when using llms_exit().
+ Avoid "Launch Course Builder" showing on orphaned lessons. [#2943](https://github.com/gocodebox/lifterlms/issues/2943)

##### Deprecations

+ Removing unused LLMS_Update class. [#1981](https://github.com/gocodebox/lifterlms/issues/1981)

##### Developer Notes

+ Adding actions for add-ons to insert additional blocks when a post is migrated to the block editor.
+ Filter for modifying the field for a Media attachement.

##### Updated Templates

+ [templates/course/outline-list-small.php](https://github.com/gocodebox/lifterlms/blob/10.0.0/templates/course/outline-list-small.php)
+ [templates/loop/pagination.php](https://github.com/gocodebox/lifterlms/blob/10.0.0/templates/loop/pagination.php)
+ [templates/single-lesson-focus.php](https://github.com/gocodebox/lifterlms/blob/10.0.0/templates/single-lesson-focus.php)


v9.2.3 - 2026-04-07
-------------------

##### Security Fixes

+ Additional permission checks when performing certain admin actions. Thanks [@nobody090909](https://github.com/nobody090909)!


v9.2.2 - 2026-03-31
-------------------

##### Updates and Enhancements

+ Various escaping and consistency changes.

##### Bug Fixes

+ Removes use of deprecated mb_convert_encoding(). [#2672](https://github.com/gocodebox/lifterlms/issues/2672)

##### Security Fixes

+ Validation of the order param for the quiz Students Without Attempts table.

##### Updated Templates

+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/9.2.2/templates/course/lesson-preview.php)
+ [templates/myaccount/my-grades-single-table.php](https://github.com/gocodebox/lifterlms/blob/9.2.2/templates/myaccount/my-grades-single-table.php)
+ [templates/quiz/questions/content-choice.php](https://github.com/gocodebox/lifterlms/blob/9.2.2/templates/quiz/questions/content-choice.php)
+ [templates/quiz/questions/content-picture_choice.php](https://github.com/gocodebox/lifterlms/blob/9.2.2/templates/quiz/questions/content-picture_choice.php)


v9.2.1 - 2026-02-02
-------------------

##### Bug Fixes

+ Fix course data calculation not ending since 9.2.0. [#3087](https://github.com/gocodebox/lifterlms/issues/3087)


v9.2.0 - 2026-01-15
-------------------

##### New Features

+ Adding "Order (High to Low)" sorting option for the Course and Membership Catalog. [#3074](https://github.com/gocodebox/lifterlms/issues/3074)
+ New global and course-level option to specify a page to redirect to upon course completion.
+ Ability to edit pricing for future charges of a recurring Order.

##### Updates and Enhancements

+ Renaming "Basic" notification to "Popup" for clarity.
+ Avoid showing license key on error.

##### Bug Fixes

+ Additional verifications when checking for an Elementor post to avoid fatal errors in some cases. [#3065](https://github.com/gocodebox/lifterlms/issues/3065)
+ Allow selection of all categories in the Courses block when there are more than 10 categories. [#3078](https://github.com/gocodebox/lifterlms/issues/3078)
+ Fixing aria label output for course favorites. Thanks [@DAnn2012](https://github.com/DAnn2012)!
+ Avoid fatal error when importing a course with an empty picture choice question. [#3070](https://github.com/gocodebox/lifterlms/issues/3070)
+ Fix protected images not loading on WPEngine hosting. [#3048](https://github.com/gocodebox/lifterlms/issues/3048)
+ Fix count of currently enrolled students in the Course overview reporting for certain hosts and number of students. [#3073](https://github.com/gocodebox/lifterlms/issues/3073)
+ Handle possible array of arrays in admin settings.

##### Updated Templates

+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/9.2.0/templates/course/favorite.php)


v9.1.2 - 2025-11-20
-------------------

##### Updates and Enhancements

+ Changed options for a new Access Plan to include gifts, and removing the Free Trial option.

##### Bug Fixes

+ Avoid warning when creating the first access plan on a course/membership. [#3046](https://github.com/gocodebox/lifterlms/issues/3046)

##### Developer Notes

+ Filters for displaying already enrolled message during checkout.
+ Filter to avoid sending a Purchase Receipt under certain conditions.
+ Filter to prevent automatic enrollment in a product after purchase completed.


v9.1.1 - 2025-11-11
-------------------

##### Security Fixes

+ Fixes security issue where student and instructor REST APIs can be used to modify roles incorrectly. Thanks [@shark3y](https://github.com/shark3y)!


v9.1.0 - 2025-11-03
-------------------

##### New Features

+ New tabs to view students who have not yet attempted a quiz, and listing of all quiz attempts for a student.
+ Option to allow unlimited time for a time-limited quiz to certain users.

##### Updates and Enhancements

+ Apply filters to save any additional fields added to LifterLMS metaboxes.
+ Adjusting syllabus styling for clarity on what can be clicked to navigate to a lesson. [#3041](https://github.com/gocodebox/lifterlms/issues/3041)
+ Template changes for improved accessibility when taking a quiz when using a keyboard or screen reader.
+ Re-label "Exit Quiz" button for clarity on resumable quizzes. [#3025](https://github.com/gocodebox/lifterlms/issues/3025)
+ Show order summary for free enrolments.
+ Removing "Estimated Completion Time" option from the Course Information block. [#3016](https://github.com/gocodebox/lifterlms/issues/3016)
+ Show warning and avoid generating invalid checkout URLs if no Checkout Page is configured. [#2984](https://github.com/gocodebox/lifterlms/issues/2984)
+ Making default password strength "weak" and changing strength requirements to minimize friction during checkout. [#2848](https://github.com/gocodebox/lifterlms/issues/2848)

##### Bug Fixes

+ Fix wording for adding a featured video on memberships. [#3034](https://github.com/gocodebox/lifterlms/issues/3034)
+ Fixing "user email required" warning when editing a LifterLMS form and changing a pattern. [#2644](https://github.com/gocodebox/lifterlms/issues/2644)

##### Developer Notes

+ Additional filter to change available merge codes for certificates.
+ Adds llms_embed_shortcode_output filter.
+ Filter to control whether a question choice is marked as correct.

##### Updated Templates

+ [templates/admin/reporting/tabs/quizzes/non-attempts.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/admin/reporting/tabs/quizzes/non-attempts.php)
+ [templates/admin/reporting/tabs/students/quiz_attempts.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/admin/reporting/tabs/students/quiz_attempts.php)
+ [templates/admin/reporting/tabs/students/student.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/admin/reporting/tabs/students/student.php)
+ [templates/checkout/form-checkout.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/checkout/form-checkout.php)
+ [templates/quiz/meta-information.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/quiz/meta-information.php)
+ [templates/quiz/questions/content-choice.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/quiz/questions/content-choice.php)
+ [templates/quiz/questions/content-picture_choice.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/quiz/questions/content-picture_choice.php)
+ [templates/quiz/results.php](https://github.com/gocodebox/lifterlms/blob/9.1.0/templates/quiz/results.php)


v9.0.7 - 2025-09-16
-------------------

##### Bug Fixes

+ Additional check to avoid conflict with certain plugins alongside the Classic Editor. [#3012](https://github.com/gocodebox/lifterlms/issues/3012)
+ Fixing checkout for countries that have no states/provinces/regions listed.


v9.0.6 - 2025-08-28
-------------------

##### Updates and Enhancements

+ Upgrades select2 library to latest release.

##### Bug Fixes

+ Avoid loading the media protection attachment scripts when not needed. [#3004](https://github.com/gocodebox/lifterlms/issues/3004)
+ Fix for "only recurring access plan" coupons. [#3002](https://github.com/gocodebox/lifterlms/issues/3002)


v9.0.5 - 2025-08-25
-------------------

##### Bug Fixes

+ Fix to allow checkout with UK and several other countries with no states/provinces/regions/areas. [#2997](https://github.com/gocodebox/lifterlms/issues/2997)


v9.0.4 - 2025-08-19
-------------------

##### Bug Fixes

+ Avoid fatal error if another plugin has loaded the Banner Notifications library.


v9.0.3 - 2025-08-19
-------------------

##### Bug Fixes

+ Additional checks for valid courses during the setup wizard. [#2992](https://github.com/gocodebox/lifterlms/issues/2992)


v9.0.2 - 2025-08-19
-------------------

##### Bug Fixes

+ Avoid fatal error during setup wizard if list of courses to import cannot be fetched. [#2992](https://github.com/gocodebox/lifterlms/issues/2992)
+ Avoid i18n translation warning on brand new site when scheduling cron. [#2990](https://github.com/gocodebox/lifterlms/issues/2990)


v9.0.1 - 2025-08-18
-------------------

##### Bug Fixes

+ Fix "unsaved changes" warning when navigating away from a course/membeship with instructors block in it. [#2986](https://github.com/gocodebox/lifterlms/issues/2986)


v9.0.0 - 2025-08-18
-------------------

##### New Features

+ Adding Mailhawk back to the email provider services.
+ Ability to protect media files for those enrolled in a specified Course or Membership.
+ Adding banner notifications.
+ Option for automatically blocking checkout spam.
+ Support for Turnstile, reCAPTCHA v3 and Akismet with checkout and registration forms.
+ Link to detach a Lesson from the course and section in the Lessons listing. [#2944](https://github.com/gocodebox/lifterlms/issues/2944)
+ Featured video and audio options for Memberships.
+ Mobile navigation for the Student Dashboard. [#2907](https://github.com/gocodebox/lifterlms/issues/2907)

##### Updates and Enhancements

+ Avoid showing hidden courses or memberships in a theme's next/previous links. [#2910](https://github.com/gocodebox/lifterlms/issues/2910)
+ Additional payment gateway information notices.
+ Avoid rendering LifterLMS blocks hidden in Text Editor blocks when using Elementor. [#2886](https://github.com/gocodebox/lifterlms/issues/2886)
+ Filter to change the method used to fetch environment variables on certain hosting configurations. [#2383](https://github.com/gocodebox/lifterlms/issues/2383)
+ Improved formatting of the individual order page.
+ Moving instructors and Estimated Length from the sidebar to the main metabox options area in Courses and Memberships.
+ Changes button text when updating a payment method,depending on whether it's a payment gateway with an external payment page. [#2957](https://github.com/gocodebox/lifterlms/issues/2957)
+ Updating countries and states/countries/provinces. [#2151](https://github.com/gocodebox/lifterlms/issues/2151)

##### Bug Fixes

+ Can select an access plan with the Access Plan Button block when more than 10 access plans exist on the site. [#2526](https://github.com/gocodebox/lifterlms/issues/2526)
+ Schedule course data recalculation throttles in the future, with new tool to clear incorrectly locked courses. [#2916](https://github.com/gocodebox/lifterlms/issues/2916)
+ Now able to clear the value from date fields. [#2977](https://github.com/gocodebox/lifterlms/issues/2977)
+ Avoid fatal error if a user who enrolled a student has been deleted, when viewing the course edit page. [#2979](https://github.com/gocodebox/lifterlms/issues/2979)
+ Avoid breaking the layout on student dashboard pages with a form (ie. Edit Account, Redeem a Voucher). [#2946](https://github.com/gocodebox/lifterlms/issues/2946)
+ Avoid console error when saving access plans when a free plan is included. [#2925](https://github.com/gocodebox/lifterlms/issues/2925)
+ Avoid duplicated buttons when changing the Engagement Type when editing an engagement. [#2962](https://github.com/gocodebox/lifterlms/issues/2962)
+ Fix link beside selected engagement when editing an engagement. [#2961](https://github.com/gocodebox/lifterlms/issues/2961)
+ Resolves warning when first visiting the Logs tab. [#2947](https://github.com/gocodebox/lifterlms/issues/2947)
+ Improved styling for course catalog and other grid layouts, including fix for course/membership featured video display.
+ Allow clearing membership restrictions without switching plan availability. [#2931](https://github.com/gocodebox/lifterlms/issues/2931)

##### Developer Notes

+ Adding hookable filter for notification sending.

##### Updated Templates

+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/checkout/form-switch-source.php)
+ [templates/loop/featured-image.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/loop/featured-image.php)
+ [templates/membership/audio.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/membership/audio.php)
+ [templates/membership/video.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/membership/video.php)
+ [templates/myaccount/my-orders.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/myaccount/my-orders.php)
+ [templates/myaccount/navigation.php](https://github.com/gocodebox/lifterlms/blob/9.0.0/templates/myaccount/navigation.php)


v8.0.7 - 2025-06-11
-------------------

##### Security Fixes

+ Additional sanitation of the voucher field.


v8.0.6 - 2025-04-21
-------------------

##### Bug Fixes

+ Fix error when editing a lesson with a drip setting of a specific date. [#2926](https://github.com/gocodebox/lifterlms/issues/2926)


v8.0.5 - 2025-04-17
-------------------

##### Updates and Enhancements

+ Modifies the allowed HTML for a form, in case the allowed post values in WP have been filtered. [#2922](https://github.com/gocodebox/lifterlms/issues/2922)


v8.0.4 - 2025-04-11
-------------------

##### Bug Fixes

+ Avoid warning and possible error when serving protected files. [#2912](https://github.com/gocodebox/lifterlms/issues/2912)


v8.0.3 - 2025-04-07
-------------------

##### New Features

+ Initial support for the Bricks theme.
+ New "# of transactions" sales reporting widget.

##### Updates and Enhancements

+ Change default date display format of lifterlms_course_info used in settings like Enrollment Start and End Date to match the site date format. [#2903](https://github.com/gocodebox/lifterlms/issues/2903)
+ Display date pickers in the site date format, but save the data in the previous format. [#2447](https://github.com/gocodebox/lifterlms/issues/2447)
+ Update Last Activity Date label to accurately reflect the data value. [#2898](https://github.com/gocodebox/lifterlms/issues/2898)

##### Bug Fixes

+ Updating postal code (eircode) display for Ireland. [#2891](https://github.com/gocodebox/lifterlms/issues/2891)
+ Net Sales reporting includes partially refunded transactions, and transactions from orders regardless of status. [#2860](https://github.com/gocodebox/lifterlms/issues/2860), [#2861](https://github.com/gocodebox/lifterlms/issues/2861)
+ On-hold, pending cancellation, cancelled and expired orders now included in "# of Sales" widget. [#2860](https://github.com/gocodebox/lifterlms/issues/2860)
+ Fixes sales reporting for transactions or orders that happened between 23:23:59 and midnight. [#2858](https://github.com/gocodebox/lifterlms/issues/2858)
+ Password reset email is now in the user's language. [#2879](https://github.com/gocodebox/lifterlms/issues/2879)

##### Developer Notes

+ Adds a new action so Turnstile or other captchas can be added without editing the free-enroll-form.php template directly.

##### Updated Templates

+ [templates/admin/reporting/tabs/students/courses-course.php](https://github.com/gocodebox/lifterlms/blob/8.0.3/templates/admin/reporting/tabs/students/courses-course.php)
+ [templates/product/free-enroll-form.php](https://github.com/gocodebox/lifterlms/blob/8.0.3/templates/product/free-enroll-form.php)


v8.0.2 - 2025-03-17
-------------------

##### Bug Fixes

+ Avoid escaping the selected attribute of a form field select dropdown incorrectly.
+ Adds additional verifications on permission for bulk enrolls, and REST API access for instructors.
+ Updates helper library to remove depreciated notice when adding a license key.

##### Security Fixes

+ Additional checks for managing LifterLMS data. Thanks [@mikemyers](https://github.com/mikemyers)!

##### Updated Templates

+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/course/favorite.php)
+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/course/lesson-preview.php)
+ [templates/global/form-login.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/global/form-login.php)
+ [templates/global/form-registration.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/global/form-registration.php)
+ [templates/loop/featured-pricing.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/loop/featured-pricing.php)
+ [templates/myaccount/form-edit-account.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/myaccount/form-edit-account.php)
+ [templates/myaccount/form-redeem-voucher.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/myaccount/form-redeem-voucher.php)
+ [templates/myaccount/my-grades-single.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/myaccount/my-grades-single.php)
+ [templates/notifications/basic.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/notifications/basic.php)
+ [templates/product/access-plan-button.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/product/access-plan-button.php)
+ [templates/product/free-enroll-form.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/product/free-enroll-form.php)
+ [templates/quiz/questions/description.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/quiz/questions/description.php)
+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/8.0.2/templates/quiz/results-attempt-questions-list.php)


v8.0.1 - 2025-02-06
-------------------

##### New Features

+ Setting to increase the frequency user tracked events are saved.

##### Bug Fixes

+ Additional escaping for form permalinks.
+ Allow quiz question to be retrieved even if attempt limit reached when resuming a quiz. [#2865](https://github.com/gocodebox/lifterlms/issues/2865)
+ Avoid grades table wrapping in the My Grades section of the student dashboard. [#2869](https://github.com/gocodebox/lifterlms/issues/2869)
+ Open the lesson panel after adding a new lesson in the Course Builder. [#2855](https://github.com/gocodebox/lifterlms/issues/2855)
+ Fixed PHP >= 8.3 warning when using WP CLI. Thanks [@jv-mtrz](https://github.com/jv-mtrz)!

##### Deprecations

+ Fixed issues with viewing quiz attempts when questions were deleted.

##### Updated Templates

+ [templates/myaccount/my-grades-single.php](https://github.com/gocodebox/lifterlms/blob/8.0.1/templates/myaccount/my-grades-single.php)
+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/8.0.1/templates/quiz/results-attempt-questions-list.php)


v8.0.0 - 2025-01-20
-------------------

##### New Features

+ New popup when adding an Access Plan with templates to help set options quickly.
+ Adds support for Beaver Builder for Courses, Memberships and Lessons. [#2761](https://github.com/gocodebox/lifterlms/issues/2761)
+ Ability to show typed password for verification on the Student Dashboard login form.
+ Adds new "Featured Pricing Information" setting for Courses and Memberships.
+ Showing 'Has Quiz' or 'Has Assignment' in the Course Syllabus.

##### Updates and Enhancements

+ Improved accessibility of various front-end and back-end UIs including the Access Plans metaboxes to use proper labels and screen reader text where needed.
+ Allow lesson access based on enrollment drip setting with Course Start Date set. [#2843](https://github.com/gocodebox/lifterlms/issues/2843)
+ Course Information header is now h2 instead of h3 by default, for accessibility in heading order.
+ Adding purchase checkout link to the access plan header as an icon. [#2793](https://github.com/gocodebox/lifterlms/issues/2793)
+ Accessibility updates for lesson favorite and write a review forms. [#2852](https://github.com/gocodebox/lifterlms/issues/2852)

##### Bug Fixes

+ Allow additional shortcodes like [audio] within the description (content) of a quiz question.
+ Can now deactivate the Confirmation field for blocks like E-mail address and Password in forms. [#2646](https://github.com/gocodebox/lifterlms/issues/2646)
+ Fix SendWP connect button. [#2792](https://github.com/gocodebox/lifterlms/issues/2792)
+ Avoid unloading the textdomain for core translations in case the lifterlms textdomain is used before init (WP 6.7). [#2807](https://github.com/gocodebox/lifterlms/issues/2807)
+ Avoid wrapping of the text of buttons. [#2820](https://github.com/gocodebox/lifterlms/issues/2820)

##### Developer Notes

+ Improved llmsPostsSelect2 method when called on multiple elements at once, each with different options. [#2805](https://github.com/gocodebox/lifterlms/issues/2805)

##### Updated Templates

+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/course/favorite.php)
+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/course/lesson-preview.php)
+ [templates/global/form-login.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/global/form-login.php)
+ [templates/global/form-registration.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/global/form-registration.php)
+ [templates/loop/featured-pricing.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/loop/featured-pricing.php)
+ [templates/myaccount/form-edit-account.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/myaccount/form-edit-account.php)
+ [templates/myaccount/form-redeem-voucher.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/myaccount/form-redeem-voucher.php)
+ [templates/notifications/basic.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/notifications/basic.php)
+ [templates/product/access-plan-button.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/product/access-plan-button.php)
+ [templates/product/free-enroll-form.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/product/free-enroll-form.php)
+ [templates/quiz/questions/description.php](https://github.com/gocodebox/lifterlms/blob/8.0.0/templates/quiz/questions/description.php)


v7.8.7 - 2024-12-17
-------------------

##### Bug Fixes

+ Fix translation error during the setup wizard. [#2835](https://github.com/gocodebox/lifterlms/issues/2835)
+ Fixes Pagespeed notice regarding deprecated Javascript event usage. [#2620](https://github.com/gocodebox/lifterlms/issues/2620)


v7.8.6 - 2024-12-16
-------------------

##### Bug Fixes

+ Adds additional check for valid quiz attempt key when ending or exiting a quiz. [#2824](https://github.com/gocodebox/lifterlms/issues/2824)
+ Fix for daylight savings and leap years when scheduling engagements. [#2799](https://github.com/gocodebox/lifterlms/issues/2799)
+ Avoid showing course opens message if no Course Start Date has been set. [#2810](https://github.com/gocodebox/lifterlms/issues/2810)
+ Improved accessibility of the lessons listing on a course page, when a lesson is restricted. [#2827](https://github.com/gocodebox/lifterlms/issues/2827)

##### Security Fixes

+ Adding additional checks before the deletion of a certificate. Thanks Lucio Sá!

##### Updated Templates

+ [templates/content-single-course-before.php](https://github.com/gocodebox/lifterlms/blob/7.8.6/templates/content-single-course-before.php)
+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/7.8.6/templates/course/lesson-preview.php)


v7.8.5 - 2024-12-03
-------------------

##### Updates and Enhancements

+ Now allows copying of text in input and textarea elements, even if copy protection is enabled.

##### Security Fixes

+ Fix to avoid saving password confirmation in user meta if Password block has been edited. [#2821](https://github.com/gocodebox/lifterlms/issues/2821)


v7.8.4 - 2024-11-18
-------------------

##### Bug Fixes

+ Fix translations not loading for LifterLMS in WordPress 6.7. [#2807](https://github.com/gocodebox/lifterlms/issues/2807)


v7.8.3 - 2024-11-04
-------------------

##### Updates and Enhancements

+ Switches new access plans to Paid by default in the new access plan UI. [#2794](https://github.com/gocodebox/lifterlms/issues/2794)


v7.8.2 - 2024-10-31
-------------------

##### Updates and Enhancements

+ Additional styling of the new Access Plan UI.

##### Bug Fixes

+ Renaming front-end javascript translation file not required, as some security scans appear to be deleting it incorrectly. [#2787](https://github.com/gocodebox/lifterlms/issues/2787)


v7.8.1 - 2024-10-29
-------------------

##### Bug Fixes

+ Fixing migration to allow SKUs to be entered in access plans if one already exists.


v7.8.0 - 2024-10-29
-------------------

##### New Features

+ Added attribute 'layout' to My Account block and shortcode to display content as columns or stacked.
+ Changes styling in the Course Syllabus block for the current lesson, when used on a single lesson page. [#2777](https://github.com/gocodebox/lifterlms/issues/2777)
+ Added new feature: Quiz Resume. [#2783](https://github.com/gocodebox/lifterlms/issues/2783)

##### Updates and Enhancements

+ Improved UI of the Access Plans UI for better usability.
+ Improved accessibility of the Access Plans metaboxes to use proper labels and screen reader text where needed.
+ Added Launch Course Builder to the WP Admin Bar when viewing a course.
+ Added Launch Course Builder button when using the Classic Editor, beside “Add Course” button.
+ Added “Clear Reporting Cache” button on admin reporting page.
+ Improved help messaging on the Course Builder, and the Account and Checkout tabs of the LifterLMS settings.
+ Added support for image upload in Result Clarifications box for quizzes.
+ Removes spacing before or after answers for conditional quiz questions.

##### Bug Fixes

+ Fixed reference in `LLMS_Ajax_Handler::quiz_start()` to `LLMS_Quiz_Attempt::get_status()` method removed since LifterLMS 4.0.0.
+ Fix for notifications no longer auto-dismissing. [#2772](https://github.com/gocodebox/lifterlms/issues/2772)
+ Fix for the lifterlms_registration shortcode not working on certain themes on a separate page. [#2779](https://github.com/gocodebox/lifterlms/issues/2779)
+ Using a more reliable method of keeping LifterLMS notices dismissed. [#2767](https://github.com/gocodebox/lifterlms/issues/2767)

##### Breaking Changes

+ Hiding the Plan SKU field for access plans if not in use. Set the `llms_access_plans_allow_skus` option to get this field back.

##### Developer Notes

+ Adds current-lesson CSS class for the current Lesson in the Course Syllabus block. [#2777](https://github.com/gocodebox/lifterlms/issues/2777)
+ Adds new llms_before_registration_validation filter for 3rd party open registration validation.
+ Added filter `llms_quiz_attempt_resume_time_period` for updating quiz resume allowed time period.

##### Updated Templates

+ [templates/admin/reporting/tabs/quizzes/attempt.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/admin/reporting/tabs/quizzes/attempt.php)
+ [templates/checkout/form-checkout.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/checkout/form-checkout.php)
+ [templates/checkout/form-summary.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/checkout/form-summary.php)
+ [templates/content-single-question.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/content-single-question.php)
+ [templates/myaccount/form-redeem-voucher.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/myaccount/form-redeem-voucher.php)
+ [templates/myaccount/header.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/myaccount/header.php)
+ [templates/notifications/basic.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/notifications/basic.php)
+ [templates/quiz/questions/content-choice.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/questions/content-choice.php)
+ [templates/quiz/questions/content-picture_choice.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/questions/content-picture_choice.php)
+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/results-attempt-questions-list.php)
+ [templates/quiz/results-attempt.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/results-attempt.php)
+ [templates/quiz/results.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/results.php)
+ [templates/quiz/start-button.php](https://github.com/gocodebox/lifterlms/blob/7.8.0/templates/quiz/start-button.php)


v7.7.8 - 2024-09-17
-------------------

##### Bug Fixes

+ Update version of the Blocks library to avoid having an unsaved changes prompt appear after updating an access plan on a course.
+ Fix for pricing display with additional formatting. [#2762](https://github.com/gocodebox/lifterlms/issues/2762)


v7.7.7 - 2024-09-12
-------------------

##### Bug Fixes

+ Avoid modifying non-LifterLMS block component styling in the editor. [#2752](https://github.com/gocodebox/lifterlms/issues/2752)
+ Use student email for the student login merge code in notification emails if usernames are not used. [#2755](https://github.com/gocodebox/lifterlms/issues/2755)
+ Show video or audio embed URLs in lessons which are valid but contain special characters. [#2749](https://github.com/gocodebox/lifterlms/issues/2749)


v7.7.6 - 2024-08-22
-------------------

##### Bug Fixes

+ Avoid modifying the Lost Password link if no LifterLMS Dashboard page is set. [#2741](https://github.com/gocodebox/lifterlms/issues/2741)
+ Fixes placeholder label on the Dashboard Page selection dropdown. [#2708](https://github.com/gocodebox/lifterlms/issues/2708)
+ Avoid outputting lifterlms_membership_link content if the membership is not published. [#2724](https://github.com/gocodebox/lifterlms/issues/2724)
+ Fix display of quiz question when viewing the quiz results if it contains formatting. [#2734](https://github.com/gocodebox/lifterlms/issues/2734)
+ Fixes sanitization as reported by FKSEC.
+ Fixes warning when trying to get the contents of a media protection file that does not exist. [#2735](https://github.com/gocodebox/lifterlms/issues/2735)

##### Updated Templates

+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/7.7.6/templates/quiz/results-attempt-questions-list.php)


v7.7.5 - 2024-08-15
-------------------

##### Bug Fixes

+ Show video tiles for courses on the Dashboard and My Courses pages when enabled. [#2728](https://github.com/gocodebox/lifterlms/issues/2728)

##### Updated Templates

+ [templates/myaccount/dashboard-section.php](https://github.com/gocodebox/lifterlms/blob/7.7.5/templates/myaccount/dashboard-section.php)


v7.7.4 - 2024-08-13
-------------------

##### Bug Fixes

+ Reverts changes to restricting pages by membership functionality to avoid conflicts with certain themes and plugins. [#2714](https://github.com/gocodebox/lifterlms/issues/2714)


v7.7.3 - 2024-08-12
-------------------

##### Bug Fixes

+ Fixes revenue display in the Orders table. [#2719](https://github.com/gocodebox/lifterlms/issues/2719)


v7.7.2 - 2024-08-12
-------------------

##### Bug Fixes

+ Fixes fatal error when updating from an old version. Thanks [@verygoodplugins](https://github.com/verygoodplugins)! [#2716](https://github.com/gocodebox/lifterlms/issues/2716)
+ Avoid errors on pages restricted by one or more memberships. [#2714](https://github.com/gocodebox/lifterlms/issues/2714)


v7.7.1 - 2024-08-09
-------------------

##### Updates and Enhancements

+ Removes placeholder image functionality with protected media files. Modify cache value for wordpress.com hosting.

##### Bug Fixes

+ Fixing the Award Certificate button appearing at the top of the Reporting > Students, Certificate tab. [#2709](https://github.com/gocodebox/lifterlms/issues/2709)
+ Fixed warnings from running `wp_kses_post()` on empty `paginate_links()` calls.

##### Updated Templates

+ [templates/myaccount/my-notifications.php](https://github.com/gocodebox/lifterlms/blob/7.7.1/templates/myaccount/my-notifications.php)


v7.7.0 - 2024-07-19
-------------------

##### New Features

+ Adding read-only input for easier sharing of a certificate. Thanks [@imknight](https://github.com/imknight)! [#1379](https://github.com/gocodebox/lifterlms/issues/1379)
+ Adds additional protection for media files uploaded to quiz questions in the Course Builder.
+ Adds native Elementor support for Courses, with a default Course template and several basic widgets.

##### Updates and Enhancements

+ Removes the Visibility setting for Vouchers and Coupons. [#2640](https://github.com/gocodebox/lifterlms/issues/2640)
+ Updating internal libraries to their latest versions.
+ Added support for mutliple membership restriction warning. [#2523](https://github.com/gocodebox/lifterlms/issues/2523)

##### Bug Fixes

+ Prevent backslashes from being removed from Result Clarifications. [#2675](https://github.com/gocodebox/lifterlms/issues/2675)
+ Avoids JS error on the front-end. [#2678](https://github.com/gocodebox/lifterlms/issues/2678)
+ Exclude hidden courses when toggled off in the Courses block. [#2690](https://github.com/gocodebox/lifterlms/issues/2690)
+ Avoids saving review meta information for non-courses. Thanks [@bsetiawan88](https://github.com/bsetiawan88)! [#887](https://github.com/gocodebox/lifterlms/issues/887)
+ Improvements to the frontend styling of LifterLMS screens for design, accessibility, and better compatibility with dark mode themes.
+ Allow private VideoPress videos to play when the URL is pasted on Video Embed URL. [#2533](https://github.com/gocodebox/lifterlms/issues/2533)
+ Fixes the Certificate Title block when creating a new certificate template. [#2696] (https://github.com/gocodebox/lifterlms/issues/2696)

##### Security Fixes

+ Adds various security improvements, e.g. better escaping of output, as suggested by the Plugin Checker Plugin.

##### Performance Improvements

+ Caching get_transaction_total queries to improve performance of the
  orders table in the admin dashboard.

##### Updated Templates

+ [templates/achievements/loop.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/achievements/loop.php)
+ [templates/achievements/template.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/achievements/template.php)
+ [templates/admin/analytics/analytics.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/analytics/analytics.php)
+ [templates/admin/notices/staging.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/notices/staging.php)
+ [templates/admin/post-types/order-transactions.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/post-types/order-transactions.php)
+ [templates/admin/post-types/students.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/post-types/students.php)
+ [templates/admin/reporting/nav-filters.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/nav-filters.php)
+ [templates/admin/reporting/reporting.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/reporting.php)
+ [templates/admin/reporting/tabs/courses/course.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/courses/course.php)
+ [templates/admin/reporting/tabs/courses/overview.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/courses/overview.php)
+ [templates/admin/reporting/tabs/courses/students.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/courses/students.php)
+ [templates/admin/reporting/tabs/memberships/membership.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/memberships/membership.php)
+ [templates/admin/reporting/tabs/memberships/overview.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/memberships/overview.php)
+ [templates/admin/reporting/tabs/memberships/students.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/memberships/students.php)
+ [templates/admin/reporting/tabs/quizzes/attempt.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/quizzes/attempt.php)
+ [templates/admin/reporting/tabs/quizzes/attempts.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/quizzes/attempts.php)
+ [templates/admin/reporting/tabs/quizzes/overview.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/quizzes/overview.php)
+ [templates/admin/reporting/tabs/quizzes/quiz.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/quizzes/quiz.php)
+ [templates/admin/reporting/tabs/students/achievements.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/achievements.php)
+ [templates/admin/reporting/tabs/students/certificates.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/certificates.php)
+ [templates/admin/reporting/tabs/students/courses-course.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/courses-course.php)
+ [templates/admin/reporting/tabs/students/courses.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/courses.php)
+ [templates/admin/reporting/tabs/students/information.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/information.php)
+ [templates/admin/reporting/tabs/students/memberships.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/memberships.php)
+ [templates/admin/reporting/tabs/students/student.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/student.php)
+ [templates/admin/reporting/tabs/students/students.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/reporting/tabs/students/students.php)
+ [templates/admin/user-edit.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/admin/user-edit.php)
+ [templates/certificates/actions.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/actions.php)
+ [templates/certificates/content-legacy.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/content-legacy.php)
+ [templates/certificates/content.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/content.php)
+ [templates/certificates/dynamic-styles.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/dynamic-styles.php)
+ [templates/certificates/header.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/header.php)
+ [templates/certificates/loop.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/loop.php)
+ [templates/certificates/preview.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/preview.php)
+ [templates/certificates/template.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/certificates/template.php)
+ [templates/checkout/form-checkout.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-checkout.php)
+ [templates/checkout/form-confirm-payment.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-confirm-payment.php)
+ [templates/checkout/form-coupon.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-coupon.php)
+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-gateways.php)
+ [templates/checkout/form-summary.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-summary.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/checkout/form-switch-source.php)
+ [templates/content-single-question.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/content-single-question.php)
+ [templates/course/audio.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/audio.php)
+ [templates/course/categories.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/categories.php)
+ [templates/course/complete-lesson-link.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/complete-lesson-link.php)
+ [templates/course/difficulty.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/difficulty.php)
+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/favorite.php)
+ [templates/course/full-description.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/full-description.php)
+ [templates/course/length.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/length.php)
+ [templates/course/lesson-count.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/lesson-count.php)
+ [templates/course/lesson-navigation.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/lesson-navigation.php)
+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/lesson-preview.php)
+ [templates/course/meta-wrapper-start.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/meta-wrapper-start.php)
+ [templates/course/outline-list-small.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/outline-list-small.php)
+ [templates/course/parent-course.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/parent-course.php)
+ [templates/course/short-description.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/short-description.php)
+ [templates/course/syllabus.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/syllabus.php)
+ [templates/course/tags.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/tags.php)
+ [templates/course/tracks.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/tracks.php)
+ [templates/course/video.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/course/video.php)
+ [templates/emails/footer.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/emails/footer.php)
+ [templates/emails/header.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/emails/header.php)
+ [templates/emails/reset-password.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/emails/reset-password.php)
+ [templates/global/form-login.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/global/form-login.php)
+ [templates/global/form-registration.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/global/form-registration.php)
+ [templates/lesson/audio.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/lesson/audio.php)
+ [templates/lesson/video.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/lesson/video.php)
+ [templates/loop/author.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/author.php)
+ [templates/loop/enroll-date.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/enroll-date.php)
+ [templates/loop/enroll-status.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/enroll-status.php)
+ [templates/loop/featured-image.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/featured-image.php)
+ [templates/loop/loop-start.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/loop-start.php)
+ [templates/loop/none-found.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/none-found.php)
+ [templates/loop/pagination.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/loop/pagination.php)
+ [templates/membership/full-description.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/membership/full-description.php)
+ [templates/membership/price.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/membership/price.php)
+ [templates/myaccount/dashboard-section.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/dashboard-section.php)
+ [templates/myaccount/form-edit-account.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/form-edit-account.php)
+ [templates/myaccount/form-redeem-voucher.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/form-redeem-voucher.php)
+ [templates/myaccount/my-favorites.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-favorites.php)
+ [templates/myaccount/my-grades-single-table.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-grades-single-table.php)
+ [templates/myaccount/my-grades-single.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-grades-single.php)
+ [templates/myaccount/my-grades.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-grades.php)
+ [templates/myaccount/my-notifications.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-notifications.php)
+ [templates/myaccount/my-orders.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/my-orders.php)
+ [templates/myaccount/navigation.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/navigation.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/view-order-actions.php)
+ [templates/myaccount/view-order-information.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/view-order-information.php)
+ [templates/myaccount/view-order-transactions.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/view-order-transactions.php)
+ [templates/myaccount/view-order.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/myaccount/view-order.php)
+ [templates/notifications/basic.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/notifications/basic.php)
+ [templates/product/access-plan-button.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-button.php)
+ [templates/product/access-plan-description.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-description.php)
+ [templates/product/access-plan-feature.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-feature.php)
+ [templates/product/access-plan-pricing.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-pricing.php)
+ [templates/product/access-plan-restrictions.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-restrictions.php)
+ [templates/product/access-plan-title.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-title.php)
+ [templates/product/access-plan-trial.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan-trial.php)
+ [templates/product/access-plan.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/access-plan.php)
+ [templates/product/free-enroll-form.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/free-enroll-form.php)
+ [templates/product/pricing-table.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/product/pricing-table.php)
+ [templates/quiz/meta-information.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/meta-information.php)
+ [templates/quiz/questions/content-choice.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/questions/content-choice.php)
+ [templates/quiz/questions/content-picture_choice.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/questions/content-picture_choice.php)
+ [templates/quiz/questions/description.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/questions/description.php)
+ [templates/quiz/questions/video.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/questions/video.php)
+ [templates/quiz/questions/wrapper-start.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/questions/wrapper-start.php)
+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/results-attempt-questions-list.php)
+ [templates/quiz/results-attempt.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/results-attempt.php)
+ [templates/quiz/results.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/results.php)
+ [templates/quiz/return-to-lesson.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/return-to-lesson.php)
+ [templates/quiz/start-button.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/quiz/start-button.php)
+ [templates/shared/instructors.php](https://github.com/gocodebox/lifterlms/blob/7.7.0/templates/shared/instructors.php)


v7.6.3 - 2024-05-31
-------------------

##### Bug Fixes

+ Adds additional filtering when using the lifterlms_favorites shortcode. Thanks, Peter Thaleikis.

##### Updated Templates

+ [templates/admin/reporting/nav-filters.php](https://github.com/gocodebox/lifterlms/blob/7.6.3/templates/admin/reporting/nav-filters.php)


v7.6.2 - 2024-05-28
-------------------

##### New Features

+ Added functionality to disable quiz retake after a passed attempt.

##### Updates and Enhancements

+ Adds ability to search by an order ID number in the Orders table. Thanks [@bsetiawan88](https://github.com/bsetiawan88)! [#1583](https://github.com/gocodebox/lifterlms/issues/1583)
+ Added support for showing Private, Drafts and Pending Courses/Memberships in Reporting > Sales Page. [#2490](https://github.com/gocodebox/lifterlms/issues/2490)

##### Bug Fixes

+ Fixes issue of not being able to save an imported or cloned course using Divi or the Classic Editor plugin. [#2649](https://github.com/gocodebox/lifterlms/issues/2649)
+ Fixes broken View link after creating a new lesson using the Course Builder. [#2662](https://github.com/gocodebox/lifterlms/issues/2662)
+ Upgrading Quill text editor version. [#2655](https://github.com/gocodebox/lifterlms/issues/2655)

##### Developer Notes

+ Added logic to delete vouchers data from table when vouchers are deleted. Thanks [@bsetiawan88](https://github.com/bsetiawan88)! [#1087](https://github.com/gocodebox/lifterlms/issues/1087)

##### Updated Templates

+ [templates/admin/reporting/nav-filters.php](https://github.com/gocodebox/lifterlms/blob/7.6.2/templates/admin/reporting/nav-filters.php)


v7.6.1 - 2024-05-02
-------------------

##### Bug Fixes

+ Fix error when trying to add a new lesson outside the course builder. [#2636](https://github.com/gocodebox/lifterlms/issues/2636)
+ Show correct course title when launching Course Builder immediately after creating a new course. [#2606](https://github.com/gocodebox/lifterlms/issues/2606)
+ Updating lifter blocks version for the Launch Course Builder button to appear on the Course edit page.


v7.6.0 - 2024-04-18
-------------------

##### New Features

+ Adds course-level lesson drip settings.
+ Loads translation files later for compatibility with plugins like Loco Translate. [#2429](https://github.com/gocodebox/lifterlms/issues/2429), [#2525](https://github.com/gocodebox/lifterlms/issues/2525)
+ Adds settings in the Permalinks page to edit the custom post type and taxonomy slugs. Slugs are saved in the site language on install on update.
+ Adds `llms_switch_to_site_locale` and `llms_restore_locale` to help LifterLMS add-ons switch to the site language when getting translation strings.

##### Updates and Enhancements

+ Improved the Course Builder UI.
+ Updating the Blocks and Helpers libraries to the latest version.

##### Bug Fixes

+ Allows the style tag when embedding content (iframe), in order to support more services. [#2610](https://github.com/gocodebox/lifterlms/issues/2610)
+ Removes non-working editing of course title in the Course Builder. [#2607](https://github.com/gocodebox/lifterlms/issues/2607)
+ Avoid issue with lost content when the course builder is launched immediately after creating a new course. [#2606](https://github.com/gocodebox/lifterlms/issues/2606)
+ LifterLMS block editor strings now appear in the user's language. [#2525](https://github.com/gocodebox/lifterlms/issues/2525)
+ Fixed user's language setting not honored on backend. [#2324](https://github.com/gocodebox/lifterlms/issues/2324)
+ Fixes XSS, sanitization, and other security issues reported by Signal Labs.
+ Fixes typo with CHF currency.

##### Updated Templates

+ [templates/myaccount/my-orders.php](https://github.com/gocodebox/lifterlms/blob/7.6.0/templates/myaccount/my-orders.php)


v7.5.3 - 2024-02-22
-------------------

##### Bug Fixes

+ Fix fatal error when rendering single course page with reviews enabled. [#2604](https://github.com/gocodebox/lifterlms/issues/2604)


v7.5.2 - 2024-02-16
-------------------

##### Updates and Enhancements

+ Added product images for Aircraft and Memberlite.
+ Updates LifterLMS Rest to [v1.0.0](https://make.lifterlms.com/2024/01/22/lifterlms-rest-api-version-1-0-0/).

##### Bug Fixes

+ Adds error handling when taking a quiz in case of temporary server error or internet issue.

##### Security Fixes

+ Reviews handler now checks nonces and user limits. Thanks, Francesco Carlucci at Wordfence.

##### Updated Templates

+ [templates/emails/footer.php](https://github.com/gocodebox/lifterlms/blob/7.5.2/templates/emails/footer.php)


v7.5.1 - 2024-01-24
-------------------

##### Updates and Enhancements

+ Added action and description links to the plugins page.

##### Bug Fixes

+ Style updates for buttons in editor.
+ Fixed logic to validate that the terms page exists before adding to email footer.
+ Removed .clear styles since WordPress already sets them by default. [#2573](https://github.com/gocodebox/lifterlms/issues/2573)
+ Improved image appearance in quiz multiple choice and image choice question types. [#2588](https://github.com/gocodebox/lifterlms/issues/2588)

##### Security Fixes

+ Added nonce for course clone link. Thanks, Dhabaleshwar Das.

##### Updated Templates

+ [templates/emails/footer.php](https://github.com/gocodebox/lifterlms/blob/7.5.1/templates/emails/footer.php)


v7.5.0 - 2023-11-05
-------------------

##### New Features

+ Added `LLMS_Add_On::get_image()` method to get the addon and author image. [#2511](https://github.com/gocodebox/lifterlms/issues/2511)
+ Added a paragraph to show Number of lessons in a course at Course Catalog and My Courses. [#2434](https://github.com/gocodebox/lifterlms/issues/2434)

##### Updates and Enhancements

+ Updates LifterLMS Blocks to [v2.5.2](https://make.lifterlms.com/2023/11/01/lifterlms-blocks-version-2-5-2/).
+ Bundled Add-ons & More Banners/Author Images in Core LifterLMS. [#2511](https://github.com/gocodebox/lifterlms/issues/2511)
+ Updates LifterLMS Rest to [v1.0.0-beta.29](https://make.lifterlms.com/2023/10/24/lifterlms-rest-api-version-1-0-0-beta-29/).
+ Update Action Scheduler to version 3.5.4. To improve compatibility with PHP 8.2.

##### Bug Fixes

+ Fixed checking for the wrong function name when defining the pluggable function `lifterlms_student_dashboard`. [#2550](https://github.com/gocodebox/lifterlms/issues/2550)
+ Only show LifterLMS-authored Addons in All section.
+ Improved compatibility with WordPress 6.4 by using `traverse_and_serialize_blocks` in place of the deprecated `_inject_theme_attribute_in_block_template_content`.
+ PHP 8.2 compatibility fix: Fixed creation of dynamic property `LLMS_Meta_Box_Access::$_saved`.

##### Developer Notes

+ Added `LLMS_Payment_Gateway::can_process_access_plan()` method to determine if an access plan can be processed by the gateway. Also added the filter hook `llms_can_gateway_process_access_plan` to filter its result.
+ Added a check on whether the gateway can process a specific plan when purchasing a plan, or switching the payment gateway of a recurring payment.
+ Added action hook `llms_checkout_form_gateway_cant_process_plan` fired on the checkout form gateways section, when a gateway cannot process a specific plan.
+ Added new filter hook `llms_unschedule_recurring_payment_on_access_pan_expiration` to control whether or not the recurring payments fo an order need to be unscheduled when the related access plan expires (`true` by default).
+ Added 'favorites' in User postmeta for getting all user's favorites.
+ Added filter `llms_course_syllabus_lesson_favorite_visibility` for disabling favorites in syllabus view.
+ Added filter `llms_is_$object_type_favorite` to change object's (lesson, student, course) favorite boolean value.
+ Added `llms_lesson_preview_before_title` and `llms_lesson_preview_after_title` action hooks.
+ Added function `llms_template_syllabus_favorite_lesson_preview`.
+ Added filter `llms_favorites_enabled` to enable/disable Favorites feature.
+ Removed references to the unused quiz's property `random_answers`. Thanks [@AlexVCS](https://github.com/AlexVCS)! [#2552](https://github.com/gocodebox/lifterlms/issues/2552)
+ Improved some unit tests compatibility with PHP 8.2.

##### Security Fixes

+ Improved security when exporting a reporting table: make sure to avoid path traversals. Thanks [Huseyin Tintas (stif)](https://linkedin.com/in/huseyintintas)!

##### Updated Templates

+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/checkout/form-switch-source.php)
+ [templates/content-single-lesson-before.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/content-single-lesson-before.php)
+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/course/favorite.php)
+ [templates/course/length.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/course/length.php)
+ [templates/course/lesson-count.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/course/lesson-count.php)
+ [templates/course/lesson-preview.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/course/lesson-preview.php)
+ [templates/loop/content.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/loop/content.php)
+ [templates/myaccount/dashboard.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/myaccount/dashboard.php)
+ [templates/myaccount/my-favorites.php](https://github.com/gocodebox/lifterlms/blob/7.5.0/templates/myaccount/my-favorites.php)


v7.4.2 - 2023-10-06
-------------------

##### Developer Notes

+ Fixing issues in the 7.4.1 release.


v7.4.1 - 2023-10-06
-------------------

##### New Features

+ Added new admin Resources page.

##### Bug Fixes

+ Fixed possible issues when cloning a course containing a quiz built with the Advanced Quizzes addon, after disabling it.

##### Developer Notes

+ Moved attempt randomization logic into the new static method `LLMS_Quiz_Attempt::randomize_attempt_questions()`.
+ Added filter hook `llms_quiz_attempt_questions_array` to allow filtering the quiz attempt's question arrays.


v7.4.0 - 2023-10-03
-------------------

##### New Features

+ Added method `LLMS_Quiz::get_questions_count()` for getting count of questions.
+ Added support for the upcoming "Question Bank" feature of the LifterLMS Advanced Quizzes add-on.

##### Updates and Enhancements

+ Added `nocache_headers()` to prevent browser caching for temporary redirects.

##### Bug Fixes

+ Added "Chaiyaphum" province for the Thailand. [#2527](https://github.com/gocodebox/lifterlms/issues/2527)

##### Developer Notes

+ Course Builder: Correctly get/set (and track changes of) Backbone's model properties which are objects.
+ Added filter hook `llms_admin_show_header` to allow 3rd parties filtering whether or not to show the branded header in the admin.
+ Added filter `llms_generator_new_post_data`, to allow third parties to filter the data used when creating a new post while cloning/exporting a course or lesson.
+ Abstracted the `LLMS_Admin_Setup_Wizard` class, added the class `LLMS_Abstract_Admin_Wizard`.
+ Added filter `llms_quiz_attempt_questions_randomize` to enable/disable questions randomize.
+ Added filter `llms_quiz_attempt_questions` to modify the questions array for the quiz.
+ Added filter `llms_quiz_questions_count` to filter the quiz's question count.

##### Updated Templates

+ [templates/quiz/meta-information.php](https://github.com/gocodebox/lifterlms/blob/7.4.0/templates/quiz/meta-information.php)


v7.3.0 - 2023-08-08
-------------------

##### Updates and Enhancements

+ When a notice is shown for an access plan on the course edit screen (e.g. When using the WooCommerce integration and no product has been associated to the access plan.) Also display a warning icon next to the access plan title.
+ Made sure only who can `view_others_lifterlms_reports` will be able to see the analytics widget content in the WordPress admin.
+ Better rounding of float values on some reporting screens.
+ Avoid creating a post revision when cloning a course/lesson.
+ When creating pages via `llms_create_pages()`: strip all tags from the page title and slash the page data prior to inserting the page in the db via `wp_insert_post()` to prevent slashes from being stripped from the page title.
+ Updated the WordPress tested version up to 6.3.
+ Improved compatibility with the Divi theme by fixing an issue with the quiz attempt result clarifications not being visible when the Divi option `Defer jQuery And jQuery Migrate` was enabled. [#2470](https://github.com/gocodebox/lifterlms/issues/2470)

##### Bug Fixes

+ Fix spacer block when creating new certificate templates in WP 6.3.
+ Fixed PHP Warning when no course/membership catalog page was set or if the selected page doesn't exist anymore. [#2496](https://github.com/gocodebox/lifterlms/issues/2496)
+ Don't include WordPress default sidebar.php template when using a block theme. [#2488](https://github.com/gocodebox/lifterlms/issues/2488)
+ Updated Kazakhstani Tenge's currency symbol. [#2475](https://github.com/gocodebox/lifterlms/issues/2475)
+ Make the dashboard widget visible only if the current user has LMS Manager capabilities. [#2500](https://github.com/gocodebox/lifterlms/issues/2500)
+ Fixed issue with LifterLMS Navigation Link block and block visibility settings. [#2474](https://github.com/gocodebox/lifterlms/issues/2474)
+ Use student dashboard as default value for navigation link block. [#2465](https://github.com/gocodebox/lifterlms/issues/2465)
+ Fixed typo in a function name that could potentially produce a fatal. Thanks [@kamalahmed](https://github.com/kamalahmed)!

##### Developer Notes

+ Added the parameter `$tab` (ID/slug of the tab) to the `lifterlms_reporting_tab_cap` filter hook. Thanks [@sapayth](https://github.com/sapayth)! [#2468](https://github.com/gocodebox/lifterlms/issues/2468)
+ Added new filter hook `llms_can_analytics_widget_be_processed` that will allow to filter whether or not an analytics widget can be processed/displayed.
+ Added new filter `llms_install_get_pages`.
+ Added new public static method `LLMS_Admin_Dashboard_Widget::get_dashboard_widget_data()`.
+ Added `llms_dashboard_checklist` and `llms_dashboard_widget_data` filters to adjust dashboard content. [#2491](https://github.com/gocodebox/lifterlms/issues/2491)

##### Updated Templates

+ [templates/admin/reporting/tabs/widgets.php](https://github.com/gocodebox/lifterlms/blob/7.3.0/templates/admin/reporting/tabs/widgets.php)
+ [templates/global/sidebar.php](https://github.com/gocodebox/lifterlms/blob/7.3.0/templates/global/sidebar.php)
+ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/7.3.0/templates/quiz/results-attempt-questions-list.php)


v7.2.1 - 2023-06-13
-------------------

##### Updates and Enhancements

+ Updated LifterLMS Blocks to [2.5.1](https://make.lifterlms.com/2023/06/13/lifterlms-blocks-version-2-5-1/). [#2461](https://github.com/gocodebox/lifterlms/issues/2461)


v7.2.0 - 2023-06-07
-------------------

##### New Features

+ Added `LLMS_ASSETS_VERSION` constant for cache busting.
+ Add course builder explainer video and lesson IDs.
+ Add new dashboard widget.
+ Added query to remove order comments on plugin uninstall when the constant `LLMS_REMOVE_ALL_DATA` is set to `true`. [#2322](https://github.com/gocodebox/lifterlms/issues/2322)
+ Added support for showing multiple difficulties when using Gutenberg Editor. [#2433](https://github.com/gocodebox/lifterlms/issues/2433)
+ Add shortcode wrapper blocks.
+ Added new navigation link block.
+ Added `llms_is_editor_block_rendering` helper function.
+ Added `llms_is_block_editor` helper function.

##### Updates and Enhancements

+ Adjusted `llms_modify_dashboard_pagination_links_disable` filter to return false only on Dashboard page.
+ Updates LifterLMS REST to [v1.0.0-beta.27](https://make.lifterlms.com/2023/05/31/lifterlms-rest-api-version-1-0-0-beta-27).
+ Raised the minimum support WordPress core version to 5.9.
+ Updates LifterLMS Blocks to [2.5.0](https://make.lifterlms.com/2023/06/06/lifterlms-blocks-version-2-5-0/).

##### Bug Fixes

+ Fixed LifterLMS specific block templates not correctly working on Windows file system.
+ Added `function_exists` check for `llms_blocks_is_post_migrated()`.
+ Update so dismissed notifications don't remain on viewport top layer.
+ Made sure to always enqueue iziModal assets when rendering achievements cards.

##### Developer Notes

+ Added new filter hook `llms_builder_settings` to filter the settings passed to the course builder.

##### Updated Templates

+ [templates/admin/reporting/tabs/widgets.php](https://github.com/gocodebox/lifterlms/blob/7.2.0/templates/admin/reporting/tabs/widgets.php)
+ [templates/course/syllabus.php](https://github.com/gocodebox/lifterlms/blob/7.2.0/templates/course/syllabus.php)


v7.1.4 - 2023-04-28
-------------------

##### Bug Fixes

+ Fixed an issue that prevented the correct saving of the course length when using the block editor. [#2426](https://github.com/gocodebox/lifterlms/issues/2426)

##### Developer Notes

+ Fixed an issue running unit tests on PHP 7.4 and WordPress 6.2 expecting `render_block()` returning a string while we were applying a filter that returned the boolean `true`.


v7.1.3 - 2023-04-25
-------------------

##### Updates and Enhancements

+ Wrapped some elements in HTML for better styling.
+ In Course and Lesson settings, replaced outdated URLs to WordPress' documentation about the list of sites you can embed from.
+ Updated few Italian province names. [#2256](https://github.com/gocodebox/lifterlms/issues/2256)
+ Avoid use of inline styles in course reviews. [#410](https://github.com/gocodebox/lifterlms/issues/410)

##### Bug Fixes

+ Fixed "Unsaved Data" warning when adding vouchers. [#2394](https://github.com/gocodebox/lifterlms/issues/2394)
+ Fixed "Course Length" and "Difficulty" fields visible in the Block Editor which is meant for Classic Editor. [#2174](https://github.com/gocodebox/lifterlms/issues/2174)
+ Added missing `$post_id` parameter to the `the_title` filter hook when retrieving a form title. [#2332](https://github.com/gocodebox/lifterlms/issues/2332)
+ Added missing Armed Forces options to the US States dropdown in the Billing information form. [#2325](https://github.com/gocodebox/lifterlms/issues/2325)
+ Using `strpos()` instead of `str_starts_with()` for compatibility. [#2415](https://github.com/gocodebox/lifterlms/issues/2415)

##### Developer Notes

+ Added helper function `llms_get_floats_rounding_precision()` to return precision for rounding off floating values and filter hook `lifterlms_floats_rounding_precision` to filter precision value in reporting. [#2237](https://github.com/gocodebox/lifterlms/issues/2237)
+ Added `lifterlms_dashboard_memberships_not_enrolled_text` filter hook to allow altering the message displaying on the student dashboard when the current user is not enrolled in any memberships. [#2396](https://github.com/gocodebox/lifterlms/issues/2396)
+ Added `lifterlms_dashboard_courses_not_enrolled_text` filter hook to allow altering the message displaying on the student dashboard when the current user is not enrolled in any courses. [#2396](https://github.com/gocodebox/lifterlms/issues/2396)

##### Updated Templates

+ [templates/course/syllabus.php](https://github.com/gocodebox/lifterlms/blob/7.1.3/templates/course/syllabus.php)


v7.1.2 - 2023-03-27
-------------------

##### Updates and Enhancements

+ Making the LifterLMS logo link to the LifterLMS.com site.

##### Bug Fixes

+ Fix bug in `llms_featured_img` function when featured image file is not available. [#2381](https://github.com/gocodebox/lifterlms/issues/2381)
+ Fixed manual certificates awarding broken when using the block editor. [#2386](https://github.com/gocodebox/lifterlms/issues/2386)


v7.1.1 - 2023-03-13
-------------------

##### Bug Fixes

+ Fixed notice display on WooCommerce dashboard pages.
+ Fixed View button URL when using WP in subdirectory.
+ Fixed blank System Report's copy for Support.


v7.1.0 - 2023-03-02
-------------------

##### New Features

+ Added lessons count column on the Courses post list table.
+ Added a new Dashboard page under the LifterLMS menu in the admin, whicih includes recent activity widgets and links to useful resources.
+ Added link to the course builder for each lesson on the Lessons post list table. Also added a link to either edit or add a quiz.

##### Updates and Enhancements

+ Updates LifterLMS Helper to [v3.5.0](https://make.lifterlms.com/2023/02/28/lifterlms-helper-version-3-5-0/).
+ Make the LifterLMS menu meta box initially available on Appearance -> Menus.
+ Updates LifterLMS REST to [v1.0.0-beta.26](https://make.lifterlms.com/2023/02/28/lifterlms-rest-api-version-1-0-0-beta-26/).

##### Bug Fixes

+ Catch possible fatal when trying to display a "broken" basic notification and set its status to 'error' so that it'll be excluded from the next fetches.
+ Catch possible fatal when sending notification emails and in that case remove from the queue the item that produced it.
+ Fix cloned course retaining original course's ID in some restriction messages.
+ Fixed possible admin notices duplication when activating/deactivating or installing add-ons from the page Add-ons & more.
+ Avoided setting the `llms-tracking` cookie when there are no events to track.
+ Updated styles across the entire plugin.
+ Updated Add-ons & more list to hide old (uncategorized) products.

##### Deprecations

+ Deprecated methods `LLMS_Admin_Notices_Core::sidebar_support()` and `LLMS_Admin_Notices_Core::clear_sidebar_notice()`.
+ Removed notice for theme sidebar support.

##### Developer Notes

+ The function `llms_is_user_enrolled()` will always return `false` for non existing users. While, before, it could return `true` if a now removed user was enrolled into a the given course or membership.
+ Added new `LLMS_Course::get_lessons_count()` method. It can be used in place of `count( LLMS_Course::get_lessons() )` to improve performance.
+ Fixed compatibility with PHP 8.1 by using an empty string as menu parent page for the course builder submenu page in place of NULL.
+ Avoid passing null values to `urlencode()` and `urldecode()` that would produce PHP warnings on PHP 8.1+.
+ Added `$autoload` parameter to the function `llms_get_student`.

##### Performance Improvements

+ Improve performance when querying notifications via the LLMS_Notifications_Query and there's no need to count the total notifications found, or for pagination information.
+ Immediately return false when running `llms_is_user_enrolled()` on logged out or no longer existing users, avoiding running additional DB queries e.g. when displaying course or membership catalogs for visitors.
+ Skip counting the total transactions found when retrieving the last or the first transaction for an order.

##### Updated Templates

+ templates/admin/reporting/nav-filters.php
+ templates/admin/reporting/reporting.php
+ templates/admin/reporting/tabs/courses/course.php
+ templates/admin/reporting/tabs/memberships/membership.php
+ templates/admin/reporting/tabs/quizzes/quiz.php
+ templates/admin/reporting/tabs/students/student.php
+ templates/admin/reporting/tabs/widgets.php
+ templates/checkout/form-confirm-payment.php


v7.0.1 - 2022-11-14
-------------------

##### Bug Fixes

+ Fixed a fatal error encountered on the payment confirmation screen when attempting to confirm a non-existent order. [#2093](https://github.com/gocodebox/lifterlms/issues/2093)
+ Use `sanitize_file_name()` in favor of `sanitize_title()` for generating the file name of reporting table export files. [#1540](https://github.com/gocodebox/lifterlms/issues/1540)
+ Resolved conflict encountered on post edit screens when using LifterLMS, Yoast SEO, and the Classic Editor plugin. [#2298](https://github.com/gocodebox/lifterlms/issues/2298)

##### Developer Notes

+ A stub method, `get_title()` has been added to the `LLMS_Abstract_Exportable_Admin_Table` abstract class. This method should be defined by any extending classes and will throw a `_doing_it_wrong()` error when undefined.
+ Added new filter to allow customizing which user roles are affected by the `LLMS_Admin_Menus::instructor_menu_hack` function.


v7.0.0 - 2022-10-04
-------------------

##### New Features

+ Added handling for admin settings options that store their option values in a nested array.
+ Added new AJAX checkout and payment source switching endpoints for payment gateways to utilize instead of the preexisting synchronous form submission methods.
+ On purchase completed retrieve the redirection URL from the INPUT_POST 'redirect' variable, if no 'redirect' variable is passed via INPUT_GET. The INPUT_POST 'redirect' variable comes from the new checkout form's hidden field 'redirect' populated with LLMS_Access_Plan::get_redirection_url(). [#2229](https://github.com/gocodebox/lifterlms/issues/2229)

##### Updates and Enhancements

+ Full Site Editing: **[BREAKING]** The wrappers in the custom header and footer templates have been changed to the semantic HTML tags `<header>` and `<footer>` in favor of default `<div>` tags. [#2281](https://github.com/gocodebox/lifterlms/issues/2281)
+ When an order post is restored from the trash its post status will now be "llms-pending" in favor of the default "draft" status.

##### Bug Fixes

+ Fixed unclosed checkout div wrapper on empty cart. [#2277](https://github.com/gocodebox/lifterlms/issues/2277)
+ Don't attempt to lookup the default payment gateway from user meta data.
+ Fixed required fields duplication when the form is a child of a `.wp-block-column` element. [#2134](https://github.com/gocodebox/lifterlms/issues/2134)
+ Fixed an issue that prevented disabling the access plan’s option, Override Membership Redirects, once enabled. [#2234](https://github.com/gocodebox/lifterlms/issues/2234)
+ Disabled `scroll-behavior: smooth` on checkout screen to address form element validity checking issues on Chromium-based browsers. [#2206](https://github.com/gocodebox/lifterlms/issues/2206)

##### Deprecations

+ Deprecated `LLMS_Controller_Orders::switch_payment_source()` in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated the `lifterlms_update_option_{$type}` action in favor of the `llms_update_option_{$type}` filter.
+ Method `LLMS_Controller_Orders::confirm_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::confirm_pending_order()`.
+ Method `LLMS_Controller_Orders::create_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::create_pending_order()`.
+ Method `LLMS_Controller_Orders::switch_payment_source()` is deprecated in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Passing jQuery selections into the `window.LLMS.Spinner` functions is deprecated. Use JS `Elements` or selection strings parseable by `document.querySelector()` instead.
+ Deprecated hook `llms_{$method}_title` in favor of `llms_{$method}_refund_title`.

##### Developer Notes

+ Added admin settings helper function, `llms_get_dashicon_link()`, intended to enable the addition of external resource helper links to settings field descriptions.
+ The `LLMS_Student` object can be instantiated as an empty object and bypass current user autoloading. In the future this may affect integrations using the `lifterlms_new_pending_order` action hook which will receive an "empty" student object during order setup by gateways utilizing new AJAX-powered checkout endpoints.
+ Added a filter, `llms_gateway_{$this->id}_logging_enabled`, which will allow force enabling/disabling of gateway logging functions.
+ Improved payment gateway secure string logging by adding a method, `add_secure_string()` allowing developers to add secure strings during runtime without the necessity of registering the strings using filters.
+ Introduces new function `llms_is_option_secure()` for determining if an "secured" option is defined in a "secure" manner.
+ Implemented new gateway feature: `modify_recurring_payments`. [#2176](https://github.com/gocodebox/lifterlms/issues/2176)
+ Added two new parameters to LLMS_Access_Plan::get_redirection_url() - `$encode` to optionally get a raw (not encoded) URL. - `$querystring_only` to optionally get only the redirect URL if set via NPUT_GET variable.
+ Added new parameter `$querystring_only` to the filter hook `llms_plan_get_checkout_redirection`.
+ Admin settings fields now display `after_html` for additional field types which support `desc`.
+ The CSS for `.llms-spinning` and `.llms-spinner` elements is no longer loaded as part of the `lifterlms.css` and `admin.css` files, instead it is loaded dynamically when `window.LLMS.Spinner` functions are called. In some cases CSS overrides to these elements which relied on CSS rule load order may no longer successfully override the default CSS rules. These overrides may need to be updated to have more specific selectors in order to ensure the overrides are retained.
+ The Javascript object, `window.LLMS.Spinner`, has been converted to a module accessible from the same variable.
+ The `window.LLMS.Spinner` methods now accept JS Elements and selector strings parseable by `document.querySelector()` in addition to jQuery selections.
+ Added new filter `llms_transaction_can_be_refunded` enabling custom refund restrictions to be applied to a transaction.

##### Updated Templates

+ [templates/block-templates/archive-course.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/archive-course.html)
+ [templates/block-templates/archive-llms_membership.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/archive-llms_membership.html)
+ [templates/block-templates/single-no-access.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/single-no-access.html)
+ [templates/block-templates/taxonomy-course_cat.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-course_cat.html)
+ [templates/block-templates/taxonomy-course_difficulty.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-course_difficulty.html)
+ [templates/block-templates/taxonomy-course_tag.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-course_tag.html)
+ [templates/block-templates/taxonomy-course_track.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-course_track.html)
+ [templates/block-templates/taxonomy-membership_cat.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-membership_cat.html)
+ [templates/block-templates/taxonomy-membership_tag.html](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/block-templates/taxonomy-membership_tag.html)
+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/checkout/form-switch-source.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.0.0/templates/myaccount/view-order-actions.php)


v6.11.0 - 2022-09-22
--------------------

##### Updates and Enhancements

+ Since version 6.0.0, the Certificate Title Block provided the option to use four Google-hosted fonts. These fonts will now be served from the site's server in favor of serving them from the Google Fonts CDN. For more information about this change, please refer to https://make.wordpress.org/themes/2022/06/18/complying-with-gdpr-when-using-google-fonts/. If you wish to continue loading fonts from Google's CDN, add the following code to your functions.php file: `add_filter( 'llms_use_google_webfonts', '__return_true' );`. [#2189](https://github.com/gocodebox/lifterlms/issues/2189)
+ Upgraded included library, `@woocommerce/action-scheduler`, to version [3.5.2](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.2).

##### Bug Fixes

+ Fixed a division by zero error encountered on quiz reporting screens for quizzes with 0 total available points. [#2270](https://github.com/gocodebox/lifterlms/issues/2270)


v7.0.0-rc.1 - 2022-09-14
------------------------

##### New Features

+ Added handling for admin settings options that store their option values in a nested array.
+ Added new AJAX checkout and payment source switching endpoints for payment gateways to utilize instead of the preexisting synchronous form submission methods.
+ On purchase completed retrieve the redirection URL from the INPUT_POST 'redirect' variable, if no 'redirect' variable is passed via INPUT_GET. The INPUT_POST 'redirect' variable comes from the new checkout form's hidden field 'redirect' populated with LLMS_Access_Plan::get_redirection_url(). [#2229](https://github.com/gocodebox/lifterlms/issues/2229)

##### Updates and Enhancements

+ When an order post is restored from the trash its post status will now be "llms-pending" in favor of the default "draft" status.

##### Bug Fixes

+ Don't attempt to lookup the default payment gateway from user meta data.
+ Fixed an issue that prevented disabling the access plan’s option, Override Membership Redirects, once enabled. [#2234](https://github.com/gocodebox/lifterlms/issues/2234)
+ Disabled `scroll-behavior: smooth` on checkout screen to address form element validity checking issues on Chromium-based browsers. [#2206](https://github.com/gocodebox/lifterlms/issues/2206)

##### Deprecations

+ Deprecated `LLMS_Controller_Orders::switch_payment_source()` in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated the `lifterlms_update_option_{$type}` action in favor of the `llms_update_option_{$type}` filter.
+ Method `LLMS_Controller_Orders::confirm_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::confirm_pending_order()`.
+ Method `LLMS_Controller_Orders::create_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::create_pending_order()`.
+ Method `LLMS_Controller_Orders::switch_payment_source()` is deprecated in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Passing jQuery selections into the `window.LLMS.Spinner` functions is deprecated. Use JS `Elements` or selection strings parseable by `document.querySelector()` instead.
+ Deprecated hook `llms_{$method}_title` in favor of `llms_{$method}_refund_title`.

##### Developer Notes

+ Added admin settings helper function, `llms_get_dashicon_link()`, intended to enable the addition of external resource helper links to settings field descriptions.
+ The `LLMS_Student` object can be instantiated as an empty object and bypass current user autoloading. In the future this may affect integrations using the `lifterlms_new_pending_order` action hook which will receive an "empty" student object during order setup by gateways utilizing new AJAX-powered checkout endpoints.
+ Added a filter, `llms_gateway_{$this->id}_logging_enabled`, which will allow force enabling/disabling of gateway logging functions.
+ Improved payment gateway secure string logging by adding a method, `add_secure_string()` allowing developers to add secure strings during runtime without the necessity of registering the strings using filters.
+ Introduces new function `llms_is_option_secure()` for determining if an "secured" option is defined in a "secure" manner.
+ Implemented new gateway feature: `modify_recurring_payments`. [#2176](https://github.com/gocodebox/lifterlms/issues/2176)
+ Added two new parameters to LLMS_Access_Plan::get_redirection_url() - `$encode` to optionally get a raw (not encoded) URL. - `$querystring_only` to optionally get only the redirect URL if set via NPUT_GET variable.
+ Added new parameter `$querystring_only` to the filter hook `llms_plan_get_checkout_redirection`.
+ Admin settings fields now display `after_html` for additional field types which support `desc`.
+ The CSS for `.llms-spinning` and `.llms-spinner` elements is no longer loaded as part of the `lifterlms.css` and `admin.css` files, instead it is loaded dynamically when `window.LLMS.Spinner` functions are called. In some cases CSS overrides to these elements which relied on CSS rule load order may no longer successfully override the default CSS rules. These overrides may need to be updated to have more specific selectors in order to ensure the overrides are retained.
+ The Javascript object, `window.LLMS.Spinner`, has been converted to a module accessible from the same variable.
+ The `window.LLMS.Spinner` methods now accept JS Elements and selector strings parseable by `document.querySelector()` in addition to jQuery selections.
+ Added new filter `llms_transaction_can_be_refunded` enabling custom refund restrictions to be applied to a transaction.

##### Updated Templates

+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-rc.1/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-rc.1/templates/checkout/form-switch-source.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-rc.1/templates/myaccount/view-order-actions.php)


v6.10.2 - 2022-09-14
--------------------

##### Updates and Enhancements

+ Updated `woocommerce/action-scheduler` to version [3.5.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.1).

##### Security Fixes

+ Fixed a data sanitization issue related to achievement permalinks.


v6.10.1 - 2022-09-07
--------------------

##### Bug Fixes

+ Fixed a PHP warning raised when logging errors during email notification dispatch. [#2250](https://github.com/gocodebox/lifterlms/issues/2250)
+ Fixed issue preventing one-time orders for being included in membership revenue reporting widgets. [#2254](https://github.com/gocodebox/lifterlms/issues/2254)


v7.0.0-beta.1 - 2022-08-29
--------------------------

##### New Features

+ Added handling for admin settings options that store their option values in a nested array.
+ Added new AJAX checkout and payment source switching endpoints for payment gateways to utilize instead of the preexisting synchronous form submission methods.
+ On purchase completed retrieve the redirection URL from the INPUT_POST 'redirect' variable, if no 'redirect' variable is passed via INPUT_GET. The INPUT_POST 'redirect' variable comes from the new checkout form's hidden field 'redirect' populated with LLMS_Access_Plan::get_redirection_url(). [#2229](https://github.com/gocodebox/lifterlms/issues/2229)

##### Updates and Enhancements

+ When an order post is restored from the trash its post status will now be "llms-pending" in favor of the default "draft" status.

##### Bug Fixes

+ Don't attempt to lookup the default payment gateway from user meta data.
+ Fixed an issue that prevented disabling the access plan’s option, Override Membership Redirects, once enabled. [#2234](https://github.com/gocodebox/lifterlms/issues/2234)
+ Disabled `scroll-behavior: smooth` on checkout screen to address form element validity checking issues on Chromium-based browsers. [#2206](https://github.com/gocodebox/lifterlms/issues/2206)

##### Deprecations

+ Deprecated `LLMS_Controller_Orders::switch_payment_source()` in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated the `lifterlms_update_option_{$type}` action in favor of the `llms_update_option_{$type}` filter.
+ Method `LLMS_Controller_Orders::confirm_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::confirm_pending_order()`.
+ Method `LLMS_Controller_Orders::create_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::create_pending_order()`.
+ Method `LLMS_Controller_Orders::switch_payment_source()` is deprecated in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Passing jQuery selections into the `window.LLMS.Spinner` functions is deprecated. Use JS `Elements` or selection strings parseable by `document.querySelector()` instead.
+ Deprecated hook `llms_{$method}_title` in favor of `llms_{$method}_refund_title`.

##### Developer Notes

+ Added admin settings helper function, `llms_get_dashicon_link()`, intended to enable the addition of external resource helper links to settings field descriptions.
+ The `LLMS_Student` object can be instantiated as an empty object and bypass current user autoloading. In the future this may affect integrations using the `lifterlms_new_pending_order` action hook which will receive an "empty" student object during order setup by gateways utilizing new AJAX-powered checkout endpoints.
+ Added a filter, `llms_gateway_{$this->id}_logging_enabled`, which will allow force enabling/disabling of gateway logging functions.
+ Improved payment gateway secure string logging by adding a method, `add_secure_string()` allowing developers to add secure strings during runtime without the necessity of registering the strings using filters.
+ Introduces new function `llms_is_option_secure()` for determining if an "secured" option is defined in a "secure" manner.
+ Implemented new gateway feature: `modify_recurring_payments`. [#2176](https://github.com/gocodebox/lifterlms/issues/2176)
+ Added two new parameters to LLMS_Access_Plan::get_redirection_url() - `$encode` to optionally get a raw (not encoded) URL. - `$querystring_only` to optionally get only the redirect URL if set via NPUT_GET variable.
+ Added new parameter `$querystring_only` to the filter hook `llms_plan_get_checkout_redirection`.
+ Admin settings fields now display `after_html` for additional field types which support `desc`.
+ The CSS for `.llms-spinning` and `.llms-spinner` elements is no longer loaded as part of the `lifterlms.css` and `admin.css` files, instead it is loaded dynamically when `window.LLMS.Spinner` functions are called. In some cases CSS overrides to these elements which relied on CSS rule load order may no longer successfully override the default CSS rules. These overrides may need to be updated to have more specific selectors in order to ensure the overrides are retained.
+ The Javascript object, `window.LLMS.Spinner`, has been converted to a module accessible from the same variable.
+ The `window.LLMS.Spinner` methods now accept JS Elements and selector strings parseable by `document.querySelector()` in addition to jQuery selections.
+ Added new filter `llms_transaction_can_be_refunded` enabling custom refund restrictions to be applied to a transaction.

##### Updated Templates

+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-beta.1/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-beta.1/templates/checkout/form-switch-source.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-beta.1/templates/myaccount/view-order-actions.php)


v6.10.0 - 2022-08-29
--------------------

##### Updates and Enhancements

+ Updtaed woocommerce/action-scheduler to version [3.5.0](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.0).
+ Upgrades the bundled `quill-wordcount` module to version 2.0, addressing an issue encountered when counting words with non-Latin character languages.

##### Bug Fixes

+ Make `<pre>` elements in quiz attempt results scrollable.
+ Make sure the current user can edit the lesson, when changing its completion status from the admin reporting.
+ Added missing textodmain for the string 'Move {post_title} to the Trash'. [#2224](https://github.com/gocodebox/lifterlms/issues/2224)
+ Fixed PHP fatal error when quick editing an award. [#2231](https://github.com/gocodebox/lifterlms/issues/2231)
+ Updated Spain's provinces list. [#2243](https://github.com/gocodebox/lifterlms/issues/2243)

##### Deprecations

+ The files `assets/vendor/quill/quill.module.wordcount.js` and `assets/vendor/quill/quill.module.wordcount.min.js` are to be removed in the next major release. Instead of loading these files directly, use `wp_enqueue_script( 'llms-quill-wordcount' )`.


v6.9.0 - 2022-07-28
-------------------

##### Updates and Enhancements

+ Removed site-wide font-weight styles targeting `<h1>` through `<h6>` elements. [#2217](https://github.com/gocodebox/lifterlms/issues/2217)

##### Bug Fixes

+ Fixed issue preventing decimals from being used for coupon discount amounts. [#2149](https://github.com/gocodebox/lifterlms/issues/2149)
+ Added AR (Arezzo) to Italy's states list. [#2214](https://github.com/gocodebox/lifterlms/issues/2214)


v7.0.0-alpha.4 - 2022-07-18
---------------------------

+ Fixed error causing recurring payment reschedules to fail with a fatal error.


v7.0.0-alpha.3 - 2022-07-16
---------------------------

+ Add max-length sanitization to admin settings which specify a max length.
+ Fixed invalid user links on admin order screens when viewing incomplete orders missing a registered user.
+ Added new function `llms_is_secure()`.
+ Added `lifterlms-` and `llms-` as automatically stripped prefixed when using `llms_strip_prefixes()`.
+ Added new temporary metadata, `temp_gateway_ids` to orders for use by gateways when switching payment methods.
+ Moved `LLMS.Spinner` Javascript into an `@lifterlms/components` module and removed its reliance on jQuery.
+ Disabled `scroll-behavior: scroll` on checkout screens to address a validity reporting issue on Chromium-based browsers.


v6.8.0 - 2022-07-12
-------------------

##### Bug Fixes

+ Fixed Hello Theme's word-break and spacing for quiz answer options. [#2132](https://github.com/gocodebox/lifterlms/issues/2132)
+ Fixed text/label alignment in Twenty-Twenty-Two theme.
+ Fixed regression introduced in version 6.3.0 which prevented the Courses nav item from being customized in the BuddyPress profile nav menu. [#2142](https://github.com/gocodebox/lifterlms/issues/2142)

##### Developer Notes

+ Added new filter `llms_product_get_restrictions` hook to filter the list of restrictions placed on a given product. [#2201](https://github.com/gocodebox/lifterlms/issues/2201)


v7.0.0-alpha.2 - 2022-06-23
---------------------------

##### New Features

+ Added handling for admin settings options that store their option values in a nested array.
+ Added new AJAX checkout and payment source switching endpoints for payment gateways to utilize instead of the preexisting synchronous form submission methods.

##### Bug Fixes

+ Don't attempt to lookup the default payment gateway from user meta data.
+ Fixes Hello Theme's word-break and spacing for quiz answer options. Also fixes text/label alignment in Twenty-Twenty-Two Theme. [#2132](https://github.com/gocodebox/lifterlms/issues/2132)

##### Deprecations

+ Deprecated `LLMS_Controller_Orders::switch_payment_source()` in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated the `lifterlms_update_option_{$type}` action in favor of the `llms_update_option_{$type}` filter.
+ Method `LLMS_Controller_Orders::confirm_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::confirm_pending_order()`.
+ Method `LLMS_Controller_Orders::create_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::create_pending_order()`.
+ Method `LLMS_Controller_Orders::switch_payment_source()` is deprecated in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated hook `llms_{$method}_title` in favor of `llms_{$method}_refund_title`.

##### Developer Notes

+ Added admin settings helper function, `llms_get_dashicon_link()`, intended to enable the addition of external resource helper links to settings field descriptions.
+ The `LLMS_Student` object can be instantiated as an empty object and bypass current user autoloading. In the future this may affect integrations using the `lifterlms_new_pending_order` action hook which will receive an "empty" student object during order setup by gateways utilizing new AJAX-powered checkout endpoints.
+ Added a filter, `llms_gateway_{$this->id}_logging_enabled`, which will allow force enabling/disabling of gateway logging functions.
+ Improved payment gateway secure string logging by adding a method, `add_secure_string()` allowing developers to add secure strings during runtime without the necessity of registering the strings using filters.
+ Implemented new gateway feature: `modify_recurring_payments`. [#2176](https://github.com/gocodebox/lifterlms/issues/2176)
+ Admin settings fields now display `after_html` for additional field types which support `desc`.
+ Added new filter `llms_transaction_can_be_refunded` enabling custom refund restrictions to be applied to a transaction.

##### Updated Templates

+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.2/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.2/templates/checkout/form-switch-source.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.2/templates/myaccount/view-order-actions.php)


v7.0.0-alpha.1 - 2022-06-15
---------------------------

##### New Features

+ Added new AJAX checkout and payment source switching endpoints for payment gateways to utilize instead of the preexisting synchronous form submission methods.

##### Bug Fixes

+ Don't attempt to lookup the default payment gateway from user meta data.

##### Deprecations

+ Deprecated `LLMS_Controller_Orders::switch_payment_source()` in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Method `LLMS_Controller_Orders::confirm_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::confirm_pending_order()`.
+ Method `LLMS_Controller_Orders::create_pending_order()` is deprecated in favor of `LLMS_Controller_Checkout::create_pending_order()`.
+ Method `LLMS_Controller_Orders::switch_payment_source()` is deprecated in favor of `LLMS_Controller_Checkout::switch_payment_source()`.
+ Deprecated hook `llms_{$method}_title` in favor of `llms_{$method}_refund_title`.

##### Developer Notes

+ The `LLMS_Student` object can be instantiated as an empty object and bypass current user autoloading. In the future this may affect integrations using the `lifterlms_new_pending_order` action hook which will receive an "empty" student object during order setup by gateways utilizing new AJAX-powered checkout endpoints.
+ Improved payment gateway secure string logging by adding a method, `add_secure_string()` allowing developers to add secure strings during runtime without the necessity of registering the strings using filters.
+ Implemented new gateway feature: `modify_recurring_payments`. [#2176](https://github.com/gocodebox/lifterlms/issues/2176)
+ Added new filter `llms_transaction_can_be_refunded` enabling custom refund restrictions to be applied to a transaction.

##### Updated Templates

+ [templates/checkout/form-gateways.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.1/templates/checkout/form-gateways.php)
+ [templates/checkout/form-switch-source.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.1/templates/checkout/form-switch-source.php)
+ [templates/myaccount/view-order-actions.php](https://github.com/gocodebox/lifterlms/blob/7.0.0-alpha.1/templates/myaccount/view-order-actions.php)


v6.7.0 - 2022-06-09
-------------------

##### Updates and Enhancements

+ Update LifterLMS Blocks to [v2.4.3](https://make.lifterlms.com/2022/06/09/lifterlms-blocks-version-2-4-3/).
+ Upgraded Action Scheduler to [v3.4.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.4.1).
+ Upgraded Action Scheduler to [v3.4.2](https://github.com/woocommerce/action-scheduler/releases/tag/3.4.2).

##### Bug Fixes

+ Fixed a fatal error on PHP 8+ when restoring a post type from revision. [#2164](https://github.com/gocodebox/lifterlms/issues/2164)


v6.6.0 - 2022-05-23
-------------------

##### PHP Minimum Required Version Change

+ **Raised the minimum supported PHP version to 7.4.**

##### WordPress Minimum Required Version Change

+ **Raised the minimum supported WordPress core version to 5.6.**

##### New Features

+ Added support for WordPress 6.0.

##### Bug Fixes

+ Fixed the ability for 3rd party plugins to use the `lifterlms_external_engagement_handler_arguments` and `lifterlms_external_engagement_query_arguments` filters.
+ Added automatic exclusion of "no cache" pages from the WP Engine server-side cache when using "pretty" permalinks. [#1717](https://github.com/gocodebox/lifterlms/issues/1717)
+ Stop subtracting LifterLMS order note comments from global comment counts via the `wp_count_comments` filter on WordPress 6.0 and later. See related WordPress Trac ticket [#19901](https://core.trac.wordpress.org/ticket/19901)


v6.5.0 - 2022-05-11
-------------------

##### Upcoming PHP Version Requirement Change

**This will be the last version of LifterLMS to support PHP 7.3. The next version of LifterLMS, expected before the end of May 2022, will raise the minimum supported PHP version to 7.4. PHP 7.3 reached its official [end of life](https://www.php.net/eol.php) on December 6, 2021. If you are still using PHP 7.3 please upgrade to PHP 7.4 or later as soon as possible.**

##### Updates and Enhancements

+ Updates LifterLMS Rest to [v1.0.0-beta.25](https://make.lifterlms.com/2022/05/11/lifterlms-rest-api-version-1-0-0-beta-25/).

##### Bug Fixes

+ Students who have already completed a lesson will now automatically bypass the lesson's drip restrictions. [#1835](https://github.com/gocodebox/lifterlms/issues/1835)
+ Properly encode certificate JS localization data. [#2140](https://github.com/gocodebox/lifterlms/issues/2140)

##### Developer Notes

+ Added a new filter, `llms_lesson_drip_bypass_if_completed`, which controls the automatic bypass of drip restrictions for completed lessons. [#1835](https://github.com/gocodebox/lifterlms/issues/1835)
+ Allow avoiding error return when updating an `LLMS_Post_Model` post meta with the same value as the one stored in the database. [#909](https://github.com/gocodebox/lifterlms/issues/909)


v6.4.0 - 2022-04-19
-------------------

##### Upcoming PHP Version Requirement Change

**LifterLMS will drop support for PHP 7.3 by May, 2022. This will raise the minimum supported PHP version to 7.4. PHP 7.3 reached its official [end of life](https://www.php.net/eol.php) on December 6, 2021. If you are still using PHP 7.3 please upgrade to PHP 7.4 or later as soon as possible.**

##### New Features

+ Any "secure" payment gateway options will be automatically masked when written to debug log files.

##### Updates and Enhancements

+ When building notification content, only parse merge codes used in the notification. [#1465](https://github.com/gocodebox/lifterlms/issues/1465)
+ Improved checks related to the number of quiz attempts allowed for each student.
+ Prevent browser page caching on quizzes. [#2092](https://github.com/gocodebox/lifterlms/issues/2092)

##### Bug Fixes

+ Allowed classes extended from the manual payment gateway class to display payment instructions.
+ Allowed the `LLMS_Shortcode_User_Info` class to be filtered by the `llms_load_shortcodes` and `llms_load_shortcode_path` hooks.
+ Stop using the deprecated `FILTER_SANITIZE_STRING` constant.
+ Fixed an issue that caused shortcodes to not be replaced in some engagement emails. [#2070](https://github.com/gocodebox/lifterlms/issues/2070)
+ Improve core forms detection so to exclude duplicates. [#2052](https://github.com/gocodebox/lifterlms/issues/2052)
+ Added Aosta (AO) to the list of Italian provinces. [#2098](https://github.com/gocodebox/lifterlms/issues/2098)
+ Fixed a compatibility issue with the Elementor Pro Theme Builder encountered on course and membership catalogs. [#2111](https://github.com/gocodebox/lifterlms/issues/2111)
+ Fixed an issue where merge codes in reusable blocks on certificate templates were not replaced when the template was displayed or when the certificate was awarded and published. [#2058](https://github.com/gocodebox/lifterlms/issues/2058)
+ Fixed an issue with OceanWP and Twenty Twenty themes where the Terms and Conditions checkbox was displayed incorrectly. [#1938](https://github.com/gocodebox/lifterlms/issues/1938)

##### Developer Notes

+ Added a new filter, `llms_secure_strings` allowing developers to register strings that should be automatically masked when written to log files.
+ Added new filter `llms_no_cache` to control whether or not LifterLMS will send nocache headers. [#2092](https://github.com/gocodebox/lifterlms/issues/2092)
+ Added new filter `llms_template_loader_restricted_priority` to control the priority of the `template_include` hook callback used to load restricted content single templates.


v6.3.0 - 2022-04-07
-------------------

##### Upcoming PHP Version Requirement Change

**LifterLMS will drop support for PHP 7.3 by May, 2022. This will raise the minimum supported PHP version to 7.4. PHP 7.3 reached its official [end of life](https://www.php.net/eol.php) on December 6, 2021. If you are still using PHP 7.3 please upgrade to PHP 7.4 or later as soon as possible.**

##### New Features

+ Automatically add student's dashboard endpoints to the BuddyPress profile nav. [#627](https://github.com/gocodebox/lifterlms/issues/627)

##### Updates and Enhancements

+ Upgraded LifterLMS Blocks to [v2.4.2](https://make.lifterlms.com/2022/04/07/lifterlms-blocks-version-2-4-2/).
+ Updated LifterLMS Helper to [v3.4.2](https://make.lifterlms.com/2022/04/01/lifterlms-helper-version-3-4-2/).

##### Bug Fixes

+ Fixed paged queries in student dashboard not working when using plain permalinks.
+ Fixed an issue that prevented searching students in some admin areas when WordPress was installed in a subdirectory. [#2096](https://github.com/gocodebox/lifterlms/issues/2096)
+ Fixed lesson's comments status not reflecting default global setting when created with the course builder. [#2099](https://github.com/gocodebox/lifterlms/issues/2099)

##### Deprecations

+ Deprecated `LLMS_Integration_Buddypress::achievements_screen()` method with no replacement.
+ Deprecated `LLMS_Integration_Buddypress::certificates_screen()` method with no replacement.
+ Deprecated `LLMS_Integration_Buddypress::courses_screen()` method with no replacement.
+ Deprecated `LLMS_Integration_Buddypress::memberships_screen()` method with no replacement.
+ Deprecated `LLMS_Integration_Buddypress::remove_courses_paginate_links_filter()` method with no replacement.
+ Deprecated `LLMS_Integration_Buddypress::modify_courses_paginate_links()` method with no replacement.

##### Developer Notes

+ Added `llms_get_paged_query_var()` function that returns the page number query var for the current request.
+ Added new filter `llms_buddypress_profile_endpoints` to control the LifterLMS endpoints to be added to the BuddyPress profile.
+ Added new filter `llms_buddypress_min_nav_item_slug` to control the LifterLMS main BuddyPress' nav item slug.
+ Added new filter `llms_buddypress_min_nav_item_label` to control the LifterLMS main BuddyPress' nav item label.
+ Added new filter `llms_buddypress_min_nav_item_position` to control the LifterLMS main BuddyPress' nav item position.


v6.2.0 - 2022-03-30
-------------------

##### Updates and Enhancements

+ Changed the `llmsStudentsSelect2()` JavaScript function to use the LifterLMS REST API "list students" endpoint instead of the `LLMS_AJAX_Handler::query_students()` PHP function.
+ Upgraded LifterLMS Blocks to [v2.4.1](https://make.lifterlms.com/2022/03/30/lifterlms-blocks-version-2-4-1/).

##### Bug Fixes

+ Fixed issue with hidden checkboxes on LifterLMS forms.
+ Fixed a compatiblity issue with the Divi Theme Builder ignoring access restrictions when using template with custom body. [#2063](https://github.com/gocodebox/lifterlms/issues/2063)
+ Fixed an error encountered on the Engagements > Certificates screen when using the BuddyBoss theme. [#2080](https://github.com/gocodebox/lifterlms/issues/2080)

##### Deprecations

+ Deprecated `LLMS_AJAX_Handler::query_students()`. Use the [REST API list students](https://developer.lifterlms.com/rest-api/#tag/Students/paths/~1students/get) endpoint instead.

##### Developer Notes

+ Added new filter `llms_template_loader_priority` to control the priority of the `template_include` hook callback used to load restricted content templates.


v6.1.0 - 2022-03-23
-------------------

##### Upcoming PHP Version Requirement Change

**LifterLMS will drop support for PHP 7.3 by May, 2022. This will raise the minimum supported PHP version to 7.4. PHP 7.3 reached its official [end of life](https://www.php.net/eol.php) on December 6, 2021. If you are still using PHP 7.3 please upgrade to PHP 7.4 or later as soon as possible.**

##### New Features

+ Added the `{earned_date}` certificate merge code.

##### Updates and Enhancements

+ Changed the label for the `{current_date}` certificate merge code from 'Earned Date' to 'Current Date'.
+ Updates LifterLMS REST to [v1.0.0-beta.24](https://make.lifterlms.com/2022/03/17/lifterlms-rest-api-version-1-0-0-beta-24/).

##### Bug Fixes

+ Fixed an issue encountered when editing an order with a completed payment plan. [#2067](https://github.com/gocodebox/lifterlms/issues/2067)
+ Fixed access of protected LLMS_Abstract_Query properties.


v6.0.0 - 2022-03-08
-------------------

**This major release of LifterLMS focuses on improving the experience of creating, designing, and managing achievements and certificates: use the block editor to design certificates, sync awards with their templates, award achievements and certificates on demand without requiring an engagement trigger, and [much more](https://lifterlms.com/docs/getting-started-with-lifterlms-6-0/). In addition, this release removes a significant number of previously deprecated classes, methods, and functions. Please read the full Breaking Changes sections for more information on removed code.**

##### New Features

+ The block editor is now enabled by default for certificates when using WordPress versions 5.8 and later.
  + Existing certificates are marked as "legacy" and will continue to use the classic editor until migrated.
  + To migrate a certificate, click the "Migrate Certificate" button. This will force the certificate's content into blocks.
+ A number of new settings are available to certificates when using the block editor:
  + Set the certificate's display (and print) size using common paper sizes such as US Letter, US Legal, A3, A4, and more.
  + Set the certificate's display orientation: portrait of landscape.
  + Set the certificate's inner margins.
  + Set the certificate's background color.
+ A new block, the Certificate Title Block, has been made available to certificates.
  + The block works like a WordPress core Heading Block with added options for selecting from a few display fonts (provided by Google Web Fonts).
  + The block controls the title of awarded certificates.
+ Added the ability for administrators and LMS managers to edit earned certificates/achievements from the students reporting screen, as well as award new certificates/achievements to students.
+ Added the ability to sync awarded certificates with the template used to generate them. [#1078](https://github.com/gocodebox/lifterlms/issues/1078)
+ The `post_name` of earned certificate posts will be generated with a randomized 3+ character string in favor of relying on sequential numbers.
+ Added certificate global options for the default size of new certificates and certificate templates.
+ Certificate and email template merge code buttons now include [llms-user] information shortcodes.
+ Added certificate sequential ID functionality merge code.
+ Added a link to return to the student dashboard when viewing an awarded certificate. [#1959](https://github.com/gocodebox/lifterlms/issues/1959)
+ Provide additional information to hooks on the student single course reporting screen.

##### Updates and Enhancements

+ Added new default images for use with achievements and certificates.
  + The site-wide default images can be customized on the admin panel under Settings -> Engagements.
  + The old default images will automatically be used for legacy certificates and can be forced by filtering `llms_use_legacy_engagement_images`. [#1081](https://github.com/gocodebox/lifterlms/issues/1081)
+ Certificates no longer use the `header.php` and `footer.php` files from the site's theme, instead custom templates (`templates/certificates/header.php` and `templates/certificates/footer.php`) are used instead. These templates are minimal and exclude theme wrappers which reduces the visual conflicts encountered from theme wrappers, backgrounds, and more, especially when printing certificates. [#463](https://github.com/gocodebox/lifterlms/issues/463)
+ The achievements and certificates dashboard endpoints are now paginated. [#669](https://github.com/gocodebox/lifterlms/issues/669)
+ Added pagination to achievement and certificate reporting pages.
+ The URL of earned user certificates has been changed from "my_certificate" to "certificate". Requests to the old url are automatically redirected to the new url, including instances where the URL slug has been translated.
+ The URL of certificate template previews has been changed from "certificate" to "certificate-template".
+ The certificate merge code, `{first_name}`, now outputs an empty string in favor of falling back to the user's nickname when there is no first name for the user. [#1640](https://github.com/gocodebox/lifterlms/issues/1640)
+ The look and behavior of the certificate {{MINI_CERTIFICATE}} pop-over notification merge code now displays a placeholder preview of the certificate in favor of attempting to render a tiny version of the actual certificate. [#1950](https://github.com/gocodebox/lifterlms/issues/1950)
+ The coupon code in the student's order details table is now wrapped in a `<code>` tag instead of an `<a>` tag. [#2033](https://github.com/gocodebox/lifterlms/issues/2033)
+ Updates LifterLMS REST to [v1.0.0-beta.23](https://make.lifterlms.com/2022/02/23/lifterlms-rest-api-version-1-0-0-beta-23/).
+ Updated LifterLMS Blocks to [version 2.4.0](https://make.lifterlms.com/2022/02/25/lifterlms-blocks-version-2-4-0/).

##### Bug Fixes

+ Delayed engagements are automatically unscheduled when the related post is deleted.
+ A disabled student dashboard endpoint will no longer display the endpoint's summary on the main dashboard page. [#535](https://github.com/gocodebox/lifterlms/issues/535)
+ Prior to sending a delayed engagement the recipient's enrollment in the related post is verified resulting the engagement not being triggered if the recipient's enrollment has been terminated. [#290](https://github.com/gocodebox/lifterlms/issues/290)
+ Post search filter boxes on various post tables will now longer display a link to the selected post.
+ Basic notification code is no longer loaded on the admin panel.
+ Fixed the label hover on picture type quizzes in some themes. [#2015](https://github.com/gocodebox/lifterlms/issues/2015)

##### Database Migration

+ A database migration is required when upgrading from versions earlier than 6.0.0. A description of the required updates can be found at [https://lifterlms.com/docs/lifterlms-database-updates/#600](https://lifterlms.com/docs/lifterlms-database-updates/#600).

##### Deprecations

+ Public access to properties of the abstract `LLMS_Database_Query` has been deprecated.
  + Public access to class property `LLMS_Database_Query::$found_results`. The property is no longer publicly writable but can be read via `LLMS_Database_Query::get_found_results()`.
  + Public access to class property `LLMS_Database_Query::$max_pages`. The property is no longer publicly writable but can be read via `LLMS_Database_Query::get_max_pages()`.
  + Public access to class property `LLMS_Database_Query::$number_results`. The property is no longer publicly writable but can be read via `LLMS_Database_Query::get_number_results()`.
  + Public access to class property `LLMS_Database_Query::$results`. The property is no longer publicly writable but can be read via `LLMS_Database_Query::get_results()`.
  + Public access to class property `LLMS_Database_Query::$query_vars`. The variable as a whole cannot be publicly accessed, instead use `LLMS_Database_Query::get()` and `LLMS_Database_Query::set()` to read and write to the array.
  + The above changes were made to the abstract class `LLMS_Database_Query` but the following concrete classes that utilize the abstract are also affected by this change: `LLMS_Query_User_Postmeta`, `LLMS_Student_Query`, `LLMS_Query_Quiz_Attempt`, `LLMS_Events_Query`, and `LLMS_Notifications_Query`.
+ Class `LLMS_Achievement_User` is deprecated with no direct replacement.
  + Method `LLMS_Achievement::is_enabled()` is deprecated with no replacement.
  + Method `LLMS_Achievement::get_blogname()` is deprecated with no replacement.
  + Method `LLMS_Achievement::format_string()` is deprecated with no replacement.
  + Method `LLMS_Achievement::get_title()` is deprecated with no replacement.
  + Method `LLMS_Achievement::get_content()` is deprecated with no replacement.
  + Method `LLMS_Achievement::get_content_html()` is deprecated with no replacement.
  + Method `LLMS_Achievement::create()` is deprecated with no replacement.
+ Method `LLMS_Achievements::trigger_engagement()` is deprecated in favor of `LLMS_Engagement_Handler::handle_achievement()`.
+ Class `LLMS_Certificate` is deprecated with no direct replacement.
  + Method `LLMS_Certificate::is_enabled()` is deprecated with no replacement.
  + Method `LLMS_Certificate::get_blogname()` is deprecated with no replacement.
  + Method `LLMS_Certificate::format_string()` is deprecated with no replacement.
  + Method `LLMS_Certificate::get_title()` is deprecated with no replacement.
  + Method `LLMS_Certificate::get_content()` is deprecated with no replacement.
  + Method `LLMS_Certificate::get_content_html()` is deprecated with no replacement.
  + Method `LLMS_Certificate::get_title()` is deprecated with no replacement.
+ Method `LLMS_Certificates::trigger_engagement()` is deprecated in favor of `LLMS_Engagement_Handler::handle_certificate()`.
+ M
Download .txt
gitextract_4knxr8ph/

├── .codeclimate.yml
├── .cursor/
│   └── BUGBOT.md
├── .editorconfig
├── .eslintrc.js
├── .github/
│   ├── CODEOWNERS
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── Bug_Report.md
│   │   ├── Feature_Request.md
│   │   └── Question.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── SECURITY.md
│   ├── workflow-matrix.yml
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── contributors.yml
│       ├── keep-alive.yml
│       ├── lint-js.yml
│       ├── ossar-analysis.yml
│       ├── project-automation.yml
│       ├── publish.yml
│       ├── sync-branches.yml
│       ├── test-e2e.yml
│       ├── test-js-unit.yml
│       └── test-phpunit.yml
├── .gitignore
├── .llmsconfig
├── .llmsdev.yml
├── .llmsdevrc
├── .llmsenv.dist
├── .source/
│   └── README.md
├── .wordpress-org/
│   ├── README.md
│   └── readme/
│       ├── 01-header.md
│       ├── 05-description.md
│       ├── 10-installation.md
│       ├── 15-faqs.md
│       ├── 20-screenshots.md
│       └── 25-changelog.md
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets/
│   ├── css/
│   │   ├── bricks-editor.css
│   │   ├── dancing-script.css
│   │   ├── imperial-script.css
│   │   ├── pirata-one.css
│   │   └── unifraktur-maguntia.css
│   ├── fonts/
│   │   └── FontAwesome.otf
│   ├── js/
│   │   ├── app/
│   │   │   ├── llms-achievements.js
│   │   │   ├── llms-ajax.js
│   │   │   ├── llms-donut.js
│   │   │   ├── llms-forms.js
│   │   │   ├── llms-instructors.js
│   │   │   ├── llms-l10n.js
│   │   │   ├── llms-lesson-preview.js
│   │   │   ├── llms-outline-collapse.js
│   │   │   ├── llms-password-strength.js
│   │   │   ├── llms-pricing-tables.js
│   │   │   ├── llms-quiz-attempt.js
│   │   │   ├── llms-review.js
│   │   │   ├── llms-storage.js
│   │   │   ├── llms-student-dashboard.js
│   │   │   ├── llms-tracking.js
│   │   │   ├── llms-visibility-toggle.js
│   │   │   └── rest.js
│   │   ├── builder/
│   │   │   ├── Collections/
│   │   │   │   ├── Lessons.js
│   │   │   │   ├── QuestionChoices.js
│   │   │   │   ├── QuestionTypes.js
│   │   │   │   ├── Questions.js
│   │   │   │   ├── Sections.js
│   │   │   │   └── loader.js
│   │   │   ├── Controllers/
│   │   │   │   ├── Construct.js
│   │   │   │   ├── Debug.js
│   │   │   │   ├── Schemas.js
│   │   │   │   └── Sync.js
│   │   │   ├── Models/
│   │   │   │   ├── Abstract.js
│   │   │   │   ├── Course.js
│   │   │   │   ├── Image.js
│   │   │   │   ├── Lesson.js
│   │   │   │   ├── Question.js
│   │   │   │   ├── QuestionChoice.js
│   │   │   │   ├── QuestionType.js
│   │   │   │   ├── Quiz.js
│   │   │   │   ├── Section.js
│   │   │   │   ├── _Relationships.js
│   │   │   │   ├── _Utilities.js
│   │   │   │   └── loader.js
│   │   │   ├── Schemas/
│   │   │   │   ├── Lesson.js
│   │   │   │   └── Quiz.js
│   │   │   ├── Views/
│   │   │   │   ├── Assignment.js
│   │   │   │   ├── Course.js
│   │   │   │   ├── Editor.js
│   │   │   │   ├── Elements.js
│   │   │   │   ├── FormattingToolbar.js
│   │   │   │   ├── Lesson.js
│   │   │   │   ├── LessonEditor.js
│   │   │   │   ├── LessonList.js
│   │   │   │   ├── Popover.js
│   │   │   │   ├── PostSearch.js
│   │   │   │   ├── Question.js
│   │   │   │   ├── QuestionBank.js
│   │   │   │   ├── QuestionChoice.js
│   │   │   │   ├── QuestionChoiceList.js
│   │   │   │   ├── QuestionList.js
│   │   │   │   ├── QuestionType.js
│   │   │   │   ├── Quiz.js
│   │   │   │   ├── Section.js
│   │   │   │   ├── SectionList.js
│   │   │   │   ├── SettingsFields.js
│   │   │   │   ├── Sidebar.js
│   │   │   │   ├── Utilities.js
│   │   │   │   ├── _Detachable.js
│   │   │   │   ├── _Editable.js
│   │   │   │   ├── _Receivable.js
│   │   │   │   ├── _Shiftable.js
│   │   │   │   ├── _Subview.js
│   │   │   │   ├── _Trashable.js
│   │   │   │   └── _loader.js
│   │   │   ├── backbone.js
│   │   │   ├── jquery.js
│   │   │   ├── main.js
│   │   │   ├── underscore.js
│   │   │   └── vendor/
│   │   │       ├── almond.js
│   │   │       ├── backbone.collectionView.js
│   │   │       ├── backbone.trackit.js
│   │   │       └── wp-hooks.js
│   │   ├── llms-admin-forms.js
│   │   ├── llms-admin-media-protection-attachment-settings.js
│   │   ├── llms-admin-settings.js
│   │   ├── llms-admin-tables.js
│   │   ├── llms-admin-wizard.js
│   │   ├── llms-admin.js
│   │   ├── llms-ajax.js
│   │   ├── llms-analytics.js
│   │   ├── llms-favorites.js
│   │   ├── llms-focus-mode.js
│   │   ├── llms-form-checkout.js
│   │   ├── llms-launch-course-button.js
│   │   ├── llms-metabox-achievement.js
│   │   ├── llms-metabox-certificate.js
│   │   ├── llms-metabox-fields.js
│   │   ├── llms-metabox-instructors.js
│   │   ├── llms-metabox-options.js
│   │   ├── llms-metabox-product.js
│   │   ├── llms-metabox-students.js
│   │   ├── llms-metabox-voucher.js
│   │   ├── llms-notifications.js
│   │   ├── llms-quiz-attempt-review.js
│   │   ├── llms-quiz.js
│   │   ├── llms-view-manager.js
│   │   ├── llms-widget-syllabus.js
│   │   ├── partials/
│   │   │   └── _metabox-field-repeater.js
│   │   ├── private/
│   │   │   ├── llms-metaboxes.js
│   │   │   └── llms.js
│   │   └── vendor/
│   │       ├── jquery.matchHeight.js
│   │       └── js.cookie.js
│   ├── scss/
│   │   ├── _includes/
│   │   │   ├── _buttons.scss
│   │   │   ├── _extends.scss
│   │   │   ├── _grid.scss
│   │   │   ├── _llms-donut.scss
│   │   │   ├── _llms-form-field.scss
│   │   │   ├── _mixins.scss
│   │   │   ├── _quiz-result-question-list.scss
│   │   │   ├── _tooltip.scss
│   │   │   ├── _vars-brand-colors.scss
│   │   │   ├── _vars.scss
│   │   │   └── vendor/
│   │   │       └── _font-awesome.scss
│   │   ├── admin/
│   │   │   ├── _course-builder.scss
│   │   │   ├── _dashboard-widget.scss
│   │   │   ├── _dashboard.scss
│   │   │   ├── _fonts.scss
│   │   │   ├── _llms-table.scss
│   │   │   ├── _main.scss
│   │   │   ├── _media-protection.scss
│   │   │   ├── _quiz-attempt-review.scss
│   │   │   ├── _reporting.scss
│   │   │   ├── _resources.scss
│   │   │   ├── _settings.scss
│   │   │   ├── _tabs.scss
│   │   │   ├── _wp-menu.scss
│   │   │   ├── breakpoints/
│   │   │   │   ├── _1030up.scss
│   │   │   │   ├── _1240up.scss
│   │   │   │   ├── _481up.scss
│   │   │   │   ├── _768up.scss
│   │   │   │   └── _base.scss
│   │   │   ├── metaboxes/
│   │   │   │   ├── _builder-launcher.scss
│   │   │   │   ├── _llms-metabox.scss
│   │   │   │   ├── _metabox-engagements-type.scss
│   │   │   │   ├── _metabox-field-repeater.scss
│   │   │   │   ├── _metabox-instructors.scss
│   │   │   │   ├── _metabox-orders.scss
│   │   │   │   ├── _metabox-product.scss
│   │   │   │   └── _metabox-students.scss
│   │   │   ├── modules/
│   │   │   │   ├── _forms.scss
│   │   │   │   ├── _icons.scss
│   │   │   │   ├── _llms-order-note.scss
│   │   │   │   ├── _mb-tabs.scss
│   │   │   │   ├── _merge-codes.scss
│   │   │   │   ├── _top-modal.scss
│   │   │   │   ├── _voucher.scss
│   │   │   │   └── _widgets.scss
│   │   │   ├── partials/
│   │   │   │   └── _grid.scss
│   │   │   └── post-tables/
│   │   │       ├── _llms_orders.scss
│   │   │       └── _post-tables.scss
│   │   ├── admin-importer.scss
│   │   ├── admin-wizard.scss
│   │   ├── admin.scss
│   │   ├── builder.scss
│   │   ├── certificates.scss
│   │   ├── editor.scss
│   │   ├── frontend/
│   │   │   ├── _checkout.scss
│   │   │   ├── _course.scss
│   │   │   ├── _focus-mode.scss
│   │   │   ├── _llms-access-plans.scss
│   │   │   ├── _llms-achievements-certs.scss
│   │   │   ├── _llms-author.scss
│   │   │   ├── _llms-notifications.scss
│   │   │   ├── _llms-outline-collapse.scss
│   │   │   ├── _llms-pagination.scss
│   │   │   ├── _llms-progress.scss
│   │   │   ├── _llms-quizzes.scss
│   │   │   ├── _llms-table.scss
│   │   │   ├── _loop.scss
│   │   │   ├── _main.scss
│   │   │   ├── _notices.scss
│   │   │   ├── _reviews.scss
│   │   │   ├── _student-dashboard.scss
│   │   │   ├── _syllabus.scss
│   │   │   ├── _tooltip.scss
│   │   │   └── _voucher.scss
│   │   ├── lifterlms.scss
│   │   └── llms-focus-mode.scss
│   └── vendor/
│       ├── a11y-dialog/
│       │   └── LICENSE
│       ├── datetimepicker/
│       │   └── jquery.datetimepicker.full.js
│       ├── izimodal/
│       │   ├── iziModal.css
│       │   └── iziModal.js
│       ├── jquery-ui-flick/
│       │   └── jquery-ui-flick.css
│       ├── quill/
│       │   ├── quill.bubble.css
│       │   ├── quill.js
│       │   ├── quill.js.LICENSE.txt
│       │   └── quill.module.wordcount.js
│       ├── select2/
│       │   ├── css/
│       │   │   └── select2.css
│       │   └── js/
│       │       └── select2.js
│       └── webui-popover/
│           ├── jquery.webui-popover.css
│           └── jquery.webui-popover.js
├── babel.config.js
├── class-lifterlms.php
├── composer.json
├── docker-compose.yml
├── docs/
│   ├── block-development.md
│   ├── coding-standards.md
│   ├── contributing.md
│   ├── documentation-standards.md
│   ├── e2e-tests-real.md
│   └── installing.md
├── gulpfile.js/
│   ├── index.js
│   └── tasks/
│       ├── hacky-clean.js
│       ├── js-additional.js
│       └── js-builder.js
├── includes/
│   ├── abstracts/
│   │   ├── abstract.llms.admin.metabox.php
│   │   ├── abstract.llms.admin.table.php
│   │   ├── abstract.llms.analytics.widget.php
│   │   ├── abstract.llms.database.query.php
│   │   ├── abstract.llms.payment.gateway.php
│   │   ├── abstract.llms.post.model.php
│   │   ├── abstract.llms.shortcode.course.element.php
│   │   ├── abstract.llms.shortcode.php
│   │   ├── abstract.llms.update.php
│   │   ├── index.php
│   │   ├── llms-abstract-admin-tool.php
│   │   ├── llms-abstract-admin-wizard.php
│   │   ├── llms-abstract-controller-user-engagements.php
│   │   ├── llms-abstract-email-provider.php
│   │   ├── llms-abstract-generator-posts.php
│   │   ├── llms-abstract-meta-box-user-engagement-sync.php
│   │   ├── llms-abstract-posts-query.php
│   │   ├── llms-abstract-processor-user-engagement-sync.php
│   │   ├── llms-abstract-query.php
│   │   ├── llms-abstract-session-data.php
│   │   ├── llms-abstract-session-database-handler.php
│   │   ├── llms-abstract-user-engagement.php
│   │   ├── llms.abstract.api.handler.php
│   │   ├── llms.abstract.database.store.php
│   │   ├── llms.abstract.exportable.admin.table.php
│   │   ├── llms.abstract.integration.php
│   │   ├── llms.abstract.notification.controller.php
│   │   ├── llms.abstract.notification.processor.php
│   │   ├── llms.abstract.notification.view.php
│   │   ├── llms.abstract.notification.view.quiz.completion.php
│   │   ├── llms.abstract.options.data.php
│   │   ├── llms.abstract.post.data.php
│   │   ├── llms.abstract.privacy.php
│   │   ├── llms.abstract.processor.php
│   │   └── llms.abstract.user.data.php
│   ├── achievements/
│   │   ├── class.llms.achievement.user.php
│   │   └── index.php
│   ├── admin/
│   │   ├── class-llms-admin-events-promo.php
│   │   ├── class-llms-admin-export-download.php
│   │   ├── class-llms-admin-header.php
│   │   ├── class-llms-admin-media-protection-attachment-settings.php
│   │   ├── class-llms-admin-permalinks.php
│   │   ├── class-llms-admin-plugins.php
│   │   ├── class-llms-admin-profile.php
│   │   ├── class-llms-admin-review.php
│   │   ├── class-llms-admin-users-table.php
│   │   ├── class-llms-export-api.php
│   │   ├── class-llms-mailhawk.php
│   │   ├── class-llms-sendwp.php
│   │   ├── class.llms.admin.addons.php
│   │   ├── class.llms.admin.assets.php
│   │   ├── class.llms.admin.builder.php
│   │   ├── class.llms.admin.dashboard-widget.php
│   │   ├── class.llms.admin.dashboard.php
│   │   ├── class.llms.admin.import.php
│   │   ├── class.llms.admin.menus.php
│   │   ├── class.llms.admin.notices.core.php
│   │   ├── class.llms.admin.notices.php
│   │   ├── class.llms.admin.page.status.php
│   │   ├── class.llms.admin.post-types.php
│   │   ├── class.llms.admin.resources.php
│   │   ├── class.llms.admin.reviews.php
│   │   ├── class.llms.admin.settings.php
│   │   ├── class.llms.admin.setup.wizard.php
│   │   ├── class.llms.admin.system-report.php
│   │   ├── class.llms.admin.user.custom.fields.php
│   │   ├── class.llms.student.bulk.enroll.php
│   │   ├── index.php
│   │   ├── llms.functions.admin.php
│   │   ├── post-types/
│   │   │   ├── class.llms.meta.boxes.php
│   │   │   ├── class.llms.post.tables.php
│   │   │   ├── index.php
│   │   │   ├── meta-boxes/
│   │   │   │   ├── class-llms-meta-box-achievement-sync.php
│   │   │   │   ├── class-llms-meta-box-certificate-sync.php
│   │   │   │   ├── class.llms.meta.box.access.php
│   │   │   │   ├── class.llms.meta.box.achievement.php
│   │   │   │   ├── class.llms.meta.box.award.engagement.submit.php
│   │   │   │   ├── class.llms.meta.box.certificate.php
│   │   │   │   ├── class.llms.meta.box.coupon.php
│   │   │   │   ├── class.llms.meta.box.course.builder.php
│   │   │   │   ├── class.llms.meta.box.course.options.php
│   │   │   │   ├── class.llms.meta.box.course.short.description.php
│   │   │   │   ├── class.llms.meta.box.email.settings.php
│   │   │   │   ├── class.llms.meta.box.engagement.php
│   │   │   │   ├── class.llms.meta.box.lesson.php
│   │   │   │   ├── class.llms.meta.box.membership.php
│   │   │   │   ├── class.llms.meta.box.order.details.php
│   │   │   │   ├── class.llms.meta.box.order.enrollment.php
│   │   │   │   ├── class.llms.meta.box.order.notes.php
│   │   │   │   ├── class.llms.meta.box.order.submit.php
│   │   │   │   ├── class.llms.meta.box.order.transactions.php
│   │   │   │   ├── class.llms.meta.box.product.php
│   │   │   │   ├── class.llms.meta.box.students.php
│   │   │   │   ├── class.llms.meta.box.visibility.php
│   │   │   │   ├── class.llms.meta.box.voucher.export.php
│   │   │   │   ├── class.llms.meta.box.voucher.php
│   │   │   │   ├── fields/
│   │   │   │   │   ├── index.php
│   │   │   │   │   ├── llms.class.meta.box.basic.editor.php
│   │   │   │   │   ├── llms.class.meta.box.button.php
│   │   │   │   │   ├── llms.class.meta.box.checkbox.php
│   │   │   │   │   ├── llms.class.meta.box.color.php
│   │   │   │   │   ├── llms.class.meta.box.custom.html.php
│   │   │   │   │   ├── llms.class.meta.box.date.php
│   │   │   │   │   ├── llms.class.meta.box.editor.php
│   │   │   │   │   ├── llms.class.meta.box.fields.php
│   │   │   │   │   ├── llms.class.meta.box.hidden.php
│   │   │   │   │   ├── llms.class.meta.box.image.php
│   │   │   │   │   ├── llms.class.meta.box.number.php
│   │   │   │   │   ├── llms.class.meta.box.post.content.php
│   │   │   │   │   ├── llms.class.meta.box.post.excerpt.php
│   │   │   │   │   ├── llms.class.meta.box.repeater.php
│   │   │   │   │   ├── llms.class.meta.box.search.php
│   │   │   │   │   ├── llms.class.meta.box.select.php
│   │   │   │   │   ├── llms.class.meta.box.table.php
│   │   │   │   │   ├── llms.class.meta.box.text.php
│   │   │   │   │   ├── llms.class.meta.box.textarea.php
│   │   │   │   │   ├── llms.class.meta.box.textarea.tags.php
│   │   │   │   │   └── llms.interface.meta.box.field.php
│   │   │   │   └── index.php
│   │   │   ├── post-tables/
│   │   │   │   ├── class-llms-admin-post-table-achievements.php
│   │   │   │   ├── class-llms-admin-post-table-awards.php
│   │   │   │   ├── class-llms-admin-post-table-certificates.php
│   │   │   │   ├── class-llms-admin-post-table-forms.php
│   │   │   │   ├── class.llms.admin.post.table.coupons.php
│   │   │   │   ├── class.llms.admin.post.table.courses.php
│   │   │   │   ├── class.llms.admin.post.table.engagements.php
│   │   │   │   ├── class.llms.admin.post.table.instructors.php
│   │   │   │   ├── class.llms.admin.post.table.lessons.php
│   │   │   │   ├── class.llms.admin.post.table.orders.php
│   │   │   │   ├── class.llms.admin.post.table.pages.php
│   │   │   │   └── index.php
│   │   │   └── tables/
│   │   │       ├── class.llms.table.student.management.php
│   │   │       └── index.php
│   │   ├── reporting/
│   │   │   ├── class.llms.admin.reporting.php
│   │   │   ├── index.php
│   │   │   ├── tables/
│   │   │   │   ├── index.php
│   │   │   │   ├── llms.table.achievements.php
│   │   │   │   ├── llms.table.certificates.php
│   │   │   │   ├── llms.table.course.students.php
│   │   │   │   ├── llms.table.courses.php
│   │   │   │   ├── llms.table.membership.students.php
│   │   │   │   ├── llms.table.memberships.php
│   │   │   │   ├── llms.table.quiz.attempts.php
│   │   │   │   ├── llms.table.quiz.non.attempts.php
│   │   │   │   ├── llms.table.quizzes.php
│   │   │   │   ├── llms.table.student.course.php
│   │   │   │   ├── llms.table.student.courses.php
│   │   │   │   ├── llms.table.student.memberships.php
│   │   │   │   ├── llms.table.student.quiz.attempts.php
│   │   │   │   └── llms.table.students.php
│   │   │   ├── tabs/
│   │   │   │   ├── class.llms.admin.reporting.tab.courses.php
│   │   │   │   ├── class.llms.admin.reporting.tab.enrollments.php
│   │   │   │   ├── class.llms.admin.reporting.tab.memberships.php
│   │   │   │   ├── class.llms.admin.reporting.tab.quizzes.php
│   │   │   │   ├── class.llms.admin.reporting.tab.sales.php
│   │   │   │   ├── class.llms.admin.reporting.tab.students.php
│   │   │   │   └── index.php
│   │   │   └── widgets/
│   │   │       ├── class.llms.analytics.widget.ajax.php
│   │   │       ├── class.llms.analytics.widget.coupons.php
│   │   │       ├── class.llms.analytics.widget.coursecompletions.php
│   │   │       ├── class.llms.analytics.widget.discounts.php
│   │   │       ├── class.llms.analytics.widget.enrollments.php
│   │   │       ├── class.llms.analytics.widget.lessoncompletions.php
│   │   │       ├── class.llms.analytics.widget.refunded.php
│   │   │       ├── class.llms.analytics.widget.refunds.php
│   │   │       ├── class.llms.analytics.widget.registrations.php
│   │   │       ├── class.llms.analytics.widget.revenue.php
│   │   │       ├── class.llms.analytics.widget.sales.php
│   │   │       ├── class.llms.analytics.widget.sold.php
│   │   │       ├── class.llms.analytics.widget.transactions.php
│   │   │       └── index.php
│   │   ├── settings/
│   │   │   ├── class.llms.settings.accounts.php
│   │   │   ├── class.llms.settings.checkout.php
│   │   │   ├── class.llms.settings.courses.php
│   │   │   ├── class.llms.settings.engagements.php
│   │   │   ├── class.llms.settings.general.php
│   │   │   ├── class.llms.settings.integrations.php
│   │   │   ├── class.llms.settings.memberships.php
│   │   │   ├── class.llms.settings.notifications.php
│   │   │   ├── class.llms.settings.page.php
│   │   │   ├── class.llms.settings.security.php
│   │   │   ├── index.php
│   │   │   └── tables/
│   │   │       ├── class.llms.table.notification.settings.php
│   │   │       └── index.php
│   │   ├── tools/
│   │   │   ├── class-llms-admin-tool-batch-eraser.php
│   │   │   ├── class-llms-admin-tool-clear-sessions.php
│   │   │   ├── class-llms-admin-tool-course-data-lock-eraser.php
│   │   │   ├── class-llms-admin-tool-install-forms.php
│   │   │   ├── class-llms-admin-tool-limited-billing-order-locator.php
│   │   │   ├── class-llms-admin-tool-recurring-payment-rescheduler.php
│   │   │   ├── class-llms-admin-tool-reset-automatic-payments.php
│   │   │   ├── class-llms-admin-tool-wipe-legacy-account-options.php
│   │   │   └── index.php
│   │   └── views/
│   │       ├── access-plans/
│   │       │   ├── access-plan-dialog.php
│   │       │   ├── access-plan.php
│   │       │   ├── index.php
│   │       │   └── metabox.php
│   │       ├── addons/
│   │       │   ├── addon-item.php
│   │       │   └── index.php
│   │       ├── builder/
│   │       │   ├── assignment.php
│   │       │   ├── course.php
│   │       │   ├── editor.php
│   │       │   ├── elements.php
│   │       │   ├── index.php
│   │       │   ├── lesson-settings.php
│   │       │   ├── lesson.php
│   │       │   ├── question-choice.php
│   │       │   ├── question-type.php
│   │       │   ├── question.php
│   │       │   ├── quiz.php
│   │       │   ├── section.php
│   │       │   ├── settings-fields.php
│   │       │   ├── sidebar.php
│   │       │   └── utilities.php
│   │       ├── dashboard/
│   │       │   ├── addons.php
│   │       │   ├── blog.php
│   │       │   ├── index.php
│   │       │   ├── podcast.php
│   │       │   └── quick-links.php
│   │       ├── dashboard.php
│   │       ├── import/
│   │       │   ├── help-sidebar.php
│   │       │   ├── help-tab-overview.php
│   │       │   └── index.php
│   │       ├── import.php
│   │       ├── importable-course.php
│   │       ├── importable-courses.php
│   │       ├── index.php
│   │       ├── merge-code-button.php
│   │       ├── metaboxes/
│   │       │   ├── index.php
│   │       │   ├── view-award-engagement-submit.php
│   │       │   ├── view-order-details.php
│   │       │   └── view-order-submit.php
│   │       ├── notices/
│   │       │   ├── db-update.php
│   │       │   ├── index.php
│   │       │   └── review-request.php
│   │       ├── reporting/
│   │       │   ├── index.php
│   │       │   └── widget.php
│   │       ├── resources/
│   │       │   ├── getting-started.php
│   │       │   ├── index.php
│   │       │   ├── resource-links.php
│   │       │   └── welcome-video.php
│   │       ├── resources.php
│   │       ├── settings.php
│   │       ├── setup-wizard/
│   │       │   ├── index.php
│   │       │   ├── main.php
│   │       │   ├── step-coupon.php
│   │       │   ├── step-finish.php
│   │       │   ├── step-intro.php
│   │       │   ├── step-pages.php
│   │       │   └── step-payments.php
│   │       ├── status/
│   │       │   ├── index.php
│   │       │   └── view-log.php
│   │       └── user-edit-fields.php
│   ├── assets/
│   │   ├── index.php
│   │   ├── llms-assets-scripts.php
│   │   └── llms-assets-styles.php
│   ├── beaver-builder/
│   │   ├── index.php
│   │   ├── modules/
│   │   │   ├── course-author/
│   │   │   │   ├── class.llms.lab.course.author.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-continue-button/
│   │   │   │   ├── class.llms.lab.course.continue.button.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-instructors/
│   │   │   │   ├── class.llms.lab.course.instructors.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-meta-info/
│   │   │   │   ├── class.llms.lab.course.meta.info.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-progress-bar/
│   │   │   │   ├── class.llms.lab.course.progress.bar.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── course-syllabus/
│   │   │   │   ├── class.llms.lab.course.syllabus.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── index.php
│   │   │   ├── lesson-mark-complete/
│   │   │   │   ├── class.llms.lab.lesson.mark.complete.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   ├── membership-instructors/
│   │   │   │   ├── class.llms.lab.membership.instructors.module.php
│   │   │   │   ├── includes/
│   │   │   │   │   ├── frontend.php
│   │   │   │   │   └── index.php
│   │   │   │   └── index.php
│   │   │   └── pricing-table/
│   │   │       ├── class.llms.lab.pricing.table.module.php
│   │   │       ├── includes/
│   │   │       │   ├── frontend.php
│   │   │       │   └── index.php
│   │   │       ├── index.php
│   │   │       └── js/
│   │   │           └── frontend.js
│   │   └── templates/
│   │       └── index.php
│   ├── bricks/
│   │   ├── class-llms-bricks-element-course-author.php
│   │   ├── class-llms-bricks-element-course-continue.php
│   │   ├── class-llms-bricks-element-course-information.php
│   │   ├── class-llms-bricks-element-course-meta-info.php
│   │   ├── class-llms-bricks-element-course-progress.php
│   │   ├── class-llms-bricks-element-course-syllabus.php
│   │   ├── class-llms-bricks-element-instructors.php
│   │   ├── class-llms-bricks-element-lesson-progression.php
│   │   └── class-llms-bricks-element-pricing-table.php
│   ├── certificates/
│   │   ├── class.llms.certificate.user.php
│   │   └── index.php
│   ├── class-llms-assets.php
│   ├── class-llms-awards-query.php
│   ├── class-llms-beaver-builder-migrate.php
│   ├── class-llms-beaver-builder.php
│   ├── class-llms-block-library.php
│   ├── class-llms-block-templates.php
│   ├── class-llms-bricks.php
│   ├── class-llms-course-completion-page.php
│   ├── class-llms-db-ugrader.php
│   ├── class-llms-dom-document.php
│   ├── class-llms-elementor-migrate.php
│   ├── class-llms-engagement-handler.php
│   ├── class-llms-events-core.php
│   ├── class-llms-events-query.php
│   ├── class-llms-events.php
│   ├── class-llms-generator-courses.php
│   ├── class-llms-grades.php
│   ├── class-llms-loader.php
│   ├── class-llms-media-protector.php
│   ├── class-llms-mime-type-extractor.php
│   ├── class-llms-order-generator.php
│   ├── class-llms-prevent-concurrent-logins.php
│   ├── class-llms-rest-fields.php
│   ├── class-llms-sessions.php
│   ├── class-llms-staging.php
│   ├── class.llms.achievement.php
│   ├── class.llms.achievements.php
│   ├── class.llms.ajax.handler.php
│   ├── class.llms.ajax.php
│   ├── class.llms.background.updater.php
│   ├── class.llms.cache.helper.php
│   ├── class.llms.certificate.php
│   ├── class.llms.certificates.php
│   ├── class.llms.comments.php
│   ├── class.llms.course.data.php
│   ├── class.llms.data.php
│   ├── class.llms.date.php
│   ├── class.llms.dot.com.api.php
│   ├── class.llms.emails.php
│   ├── class.llms.engagements.php
│   ├── class.llms.frontend.assets.php
│   ├── class.llms.gateway.manual.php
│   ├── class.llms.generator.php
│   ├── class.llms.hasher.php
│   ├── class.llms.https.php
│   ├── class.llms.install.php
│   ├── class.llms.integrations.php
│   ├── class.llms.l10n.php
│   ├── class.llms.lesson.handler.php
│   ├── class.llms.membership.data.php
│   ├── class.llms.nav.menus.php
│   ├── class.llms.oembed.php
│   ├── class.llms.payment.gateways.php
│   ├── class.llms.person.handler.php
│   ├── class.llms.playnice.php
│   ├── class.llms.post-types.php
│   ├── class.llms.post.handler.php
│   ├── class.llms.post.relationships.php
│   ├── class.llms.query.php
│   ├── class.llms.query.quiz.attempt.php
│   ├── class.llms.query.user.postmeta.php
│   ├── class.llms.question.manager.php
│   ├── class.llms.question.types.php
│   ├── class.llms.quiz.data.php
│   ├── class.llms.review.php
│   ├── class.llms.roles.php
│   ├── class.llms.session.php
│   ├── class.llms.sidebars.php
│   ├── class.llms.site.php
│   ├── class.llms.student.dashboard.php
│   ├── class.llms.student.query.php
│   ├── class.llms.template.loader.php
│   ├── class.llms.track.php
│   ├── class.llms.tracker.php
│   ├── class.llms.user.permissions.php
│   ├── class.llms.view.manager.php
│   ├── class.llms.voucher.php
│   ├── controllers/
│   │   ├── class-llms-controller-awards.php
│   │   ├── class-llms-controller-checkout.php
│   │   ├── class.llms.controller.achievements.php
│   │   ├── class.llms.controller.admin.quiz.attempts.php
│   │   ├── class.llms.controller.certificates.php
│   │   ├── class.llms.controller.lesson.progression.php
│   │   ├── class.llms.controller.orders.php
│   │   ├── class.llms.controller.quizzes.php
│   │   └── index.php
│   ├── elementor/
│   │   ├── class-llms-elementor-widget-base.php
│   │   ├── class-llms-elementor-widget-course-continue-button.php
│   │   ├── class-llms-elementor-widget-course-instructors.php
│   │   ├── class-llms-elementor-widget-course-meta-info.php
│   │   ├── class-llms-elementor-widget-course-progress.php
│   │   ├── class-llms-elementor-widget-course-syllabus.php
│   │   ├── class-llms-elementor-widget-pricing-table.php
│   │   └── class-llms-elementor-widgets.php
│   ├── emails/
│   │   ├── class.llms.email.engagement.php
│   │   ├── class.llms.email.php
│   │   ├── class.llms.email.reset.password.php
│   │   └── index.php
│   ├── forms/
│   │   ├── class-llms-form-field.php
│   │   ├── class-llms-form-handler.php
│   │   ├── class-llms-form-post-type.php
│   │   ├── class-llms-form-templates.php
│   │   ├── class-llms-form-validator.php
│   │   ├── class-llms-forms-admin-bar.php
│   │   ├── class-llms-forms-classic-editor.php
│   │   ├── class-llms-forms-data.php
│   │   ├── class-llms-forms-dynamic-fields.php
│   │   ├── class-llms-forms-unsupported-versions.php
│   │   ├── class-llms-forms.php
│   │   ├── controllers/
│   │   │   ├── class.llms.controller.account.php
│   │   │   ├── class.llms.controller.login.php
│   │   │   ├── class.llms.controller.registration.php
│   │   │   └── index.php
│   │   └── index.php
│   ├── functions/
│   │   ├── index.php
│   │   ├── llms-functions-access-plans.php
│   │   ├── llms-functions-conditional-tags.php
│   │   ├── llms-functions-content.php
│   │   ├── llms-functions-deprecated.php
│   │   ├── llms-functions-forms.php
│   │   ├── llms-functions-l10n.php
│   │   ├── llms-functions-locale.php
│   │   ├── llms-functions-options.php
│   │   ├── llms-functions-progression.php
│   │   ├── llms-functions-template-view-order.php
│   │   ├── llms-functions-templates-courses.php
│   │   ├── llms-functions-templates-memberships.php
│   │   ├── llms-functions-templates-shared.php
│   │   ├── llms-functions-user-information-fields.php
│   │   ├── llms-functions-wrappers.php
│   │   ├── llms.functions.access.php
│   │   ├── llms.functions.certificate.php
│   │   ├── llms.functions.course.php
│   │   ├── llms.functions.currency.php
│   │   ├── llms.functions.favorite.php
│   │   ├── llms.functions.log.php
│   │   ├── llms.functions.notice.php
│   │   ├── llms.functions.order.php
│   │   ├── llms.functions.page.php
│   │   ├── llms.functions.person.php
│   │   ├── llms.functions.privacy.php
│   │   ├── llms.functions.quiz.php
│   │   ├── llms.functions.template.php
│   │   ├── llms.functions.templates.achievements.php
│   │   ├── llms.functions.templates.certificates.php
│   │   ├── llms.functions.templates.dashboard.php
│   │   ├── llms.functions.templates.dashboard.widgets.php
│   │   ├── llms.functions.templates.loop.php
│   │   ├── llms.functions.templates.pricing.table.php
│   │   ├── llms.functions.templates.privacy.php
│   │   ├── llms.functions.templates.quizzes.php
│   │   ├── llms.functions.updates.php
│   │   ├── llms.functions.user.postmeta.php
│   │   └── updates/
│   │       ├── index.php
│   │       ├── llms-functions-updates-300.php
│   │       ├── llms-functions-updates-303.php
│   │       ├── llms-functions-updates-3120.php
│   │       ├── llms-functions-updates-3130.php
│   │       ├── llms-functions-updates-3160.php
│   │       ├── llms-functions-updates-3280.php
│   │       ├── llms-functions-updates-343.php
│   │       ├── llms-functions-updates-360.php
│   │       ├── llms-functions-updates-380.php
│   │       ├── llms-functions-updates-400.php
│   │       ├── llms-functions-updates-4150.php
│   │       ├── llms-functions-updates-450.php
│   │       ├── llms-functions-updates-500.php
│   │       ├── llms-functions-updates-520.php
│   │       ├── llms-functions-updates-600.php
│   │       ├── llms-functions-updates-6100.php
│   │       ├── llms-functions-updates-630.php
│   │       ├── llms-functions-updates-750.php
│   │       ├── llms-functions-updates-780.php
│   │       ├── llms-functions-updates-785.php
│   │       ├── llms-functions-updates-900.php
│   │       └── llms-functions-updates-921.php
│   ├── index.php
│   ├── integrations/
│   │   ├── class.llms.integration.bbpress.php
│   │   ├── class.llms.integration.buddypress.php
│   │   └── index.php
│   ├── interfaces/
│   │   ├── index.php
│   │   ├── interface.llms.notification.manager.php
│   │   ├── llms.interface.notification.controller.php
│   │   └── llms.interface.post.instructors.php
│   ├── llms-notifications.php
│   ├── llms.functions.core.php
│   ├── llms.spam.functions.php
│   ├── llms.template.functions.php
│   ├── llms.template.hooks.php
│   ├── models/
│   │   ├── class-llms-event.php
│   │   ├── index.php
│   │   ├── model.llms.access.plan.php
│   │   ├── model.llms.add-on.php
│   │   ├── model.llms.coupon.php
│   │   ├── model.llms.course.php
│   │   ├── model.llms.instructor.php
│   │   ├── model.llms.lesson.php
│   │   ├── model.llms.membership.php
│   │   ├── model.llms.notification.php
│   │   ├── model.llms.order.php
│   │   ├── model.llms.post.instructors.php
│   │   ├── model.llms.product.php
│   │   ├── model.llms.question.choice.php
│   │   ├── model.llms.question.php
│   │   ├── model.llms.quiz.attempt.php
│   │   ├── model.llms.quiz.attempt.question.php
│   │   ├── model.llms.quiz.php
│   │   ├── model.llms.section.php
│   │   ├── model.llms.student.php
│   │   ├── model.llms.student.quizzes.php
│   │   ├── model.llms.transaction.php
│   │   ├── model.llms.user.achievement.php
│   │   ├── model.llms.user.certificate.php
│   │   └── model.llms.user.postmeta.php
│   ├── notifications/
│   │   ├── class.llms.notifications.php
│   │   ├── class.llms.notifications.query.php
│   │   ├── controllers/
│   │   │   ├── class.llms.notification.controller.achievement.earned.php
│   │   │   ├── class.llms.notification.controller.certificate.earned.php
│   │   │   ├── class.llms.notification.controller.course.complete.php
│   │   │   ├── class.llms.notification.controller.course.track.complete.php
│   │   │   ├── class.llms.notification.controller.enrollment.php
│   │   │   ├── class.llms.notification.controller.lesson.complete.php
│   │   │   ├── class.llms.notification.controller.manual.payment.due.php
│   │   │   ├── class.llms.notification.controller.payment.retry.php
│   │   │   ├── class.llms.notification.controller.purchase.receipt.php
│   │   │   ├── class.llms.notification.controller.quiz.failed.php
│   │   │   ├── class.llms.notification.controller.quiz.graded.php
│   │   │   ├── class.llms.notification.controller.quiz.passed.php
│   │   │   ├── class.llms.notification.controller.section.complete.php
│   │   │   ├── class.llms.notification.controller.student.welcome.php
│   │   │   ├── class.llms.notification.controller.subscription.cancelled.php
│   │   │   ├── class.llms.notification.controller.upcoming.payment.reminder.php
│   │   │   └── index.php
│   │   ├── index.php
│   │   ├── processors/
│   │   │   ├── class.llms.notification.processor.email.php
│   │   │   └── index.php
│   │   └── views/
│   │       ├── class.llms.notification.view.achievement.earned.php
│   │       ├── class.llms.notification.view.certificate.earned.php
│   │       ├── class.llms.notification.view.course.complete.php
│   │       ├── class.llms.notification.view.course.track.complete.php
│   │       ├── class.llms.notification.view.enrollment.php
│   │       ├── class.llms.notification.view.lesson.complete.php
│   │       ├── class.llms.notification.view.manual.payment.due.php
│   │       ├── class.llms.notification.view.payment.retry.php
│   │       ├── class.llms.notification.view.purchase.receipt.php
│   │       ├── class.llms.notification.view.quiz.failed.php
│   │       ├── class.llms.notification.view.quiz.graded.php
│   │       ├── class.llms.notification.view.quiz.passed.php
│   │       ├── class.llms.notification.view.section.complete.php
│   │       ├── class.llms.notification.view.student.welcome.php
│   │       ├── class.llms.notification.view.subscription.cancelled.php
│   │       ├── class.llms.notification.view.upcoming.payment.reminder.php
│   │       └── index.php
│   ├── privacy/
│   │   ├── class-llms-privacy-erasers.php
│   │   ├── class-llms-privacy-exporters.php
│   │   ├── class-llms-privacy.php
│   │   └── index.php
│   ├── processors/
│   │   ├── class-llms-processor-achievement-sync.php
│   │   ├── class-llms-processor-certificate-sync.php
│   │   ├── class.llms.processor.course.data.php
│   │   ├── class.llms.processor.membership.bulk.enroll.php
│   │   ├── class.llms.processors.php
│   │   └── index.php
│   ├── schemas/
│   │   ├── index.php
│   │   ├── llms-block-templates.php
│   │   ├── llms-db-updates.php
│   │   ├── llms-form-locations.php
│   │   ├── llms-reusable-blocks.php
│   │   └── llms-user-information-fields.php
│   ├── shortcodes/
│   │   ├── class-llms-shortcode-user-info.php
│   │   ├── class.llms.bbp.shortcode.course.forums.list.php
│   │   ├── class.llms.shortcode.checkout.php
│   │   ├── class.llms.shortcode.course.author.php
│   │   ├── class.llms.shortcode.course.continue.button.php
│   │   ├── class.llms.shortcode.course.continue.php
│   │   ├── class.llms.shortcode.course.instructors.php
│   │   ├── class.llms.shortcode.course.meta.info.php
│   │   ├── class.llms.shortcode.course.outline.php
│   │   ├── class.llms.shortcode.course.prerequisites.php
│   │   ├── class.llms.shortcode.course.reviews.php
│   │   ├── class.llms.shortcode.course.syllabus.php
│   │   ├── class.llms.shortcode.courses.php
│   │   ├── class.llms.shortcode.favorites.php
│   │   ├── class.llms.shortcode.hide.content.php
│   │   ├── class.llms.shortcode.lesson.mark.complete.php
│   │   ├── class.llms.shortcode.lesson.navigation.php
│   │   ├── class.llms.shortcode.membership.instructors.php
│   │   ├── class.llms.shortcode.membership.link.php
│   │   ├── class.llms.shortcode.my.account.php
│   │   ├── class.llms.shortcode.my.achievements.php
│   │   ├── class.llms.shortcode.registration.php
│   │   ├── class.llms.shortcodes.blocks.php
│   │   ├── class.llms.shortcodes.php
│   │   └── index.php
│   ├── spam/
│   │   ├── class-llms-akismet.php
│   │   ├── class-llms-captcha.php
│   │   ├── class-llms-recaptcha.php
│   │   └── class-llms-turnstile.php
│   ├── theme-support/
│   │   ├── class-llms-theme-support.php
│   │   ├── class-llms-twenty-nineteen.php
│   │   ├── class-llms-twenty-twenty-one.php
│   │   ├── class-llms-twenty-twenty-two.php
│   │   ├── class-llms-twenty-twenty.php
│   │   └── index.php
│   ├── traits/
│   │   ├── llms-trait-audio-video-embed.php
│   │   ├── llms-trait-award-default-images.php
│   │   ├── llms-trait-award-templates-post-list-table.php
│   │   ├── llms-trait-earned-engagement-reporting-table.php
│   │   ├── llms-trait-sales-page.php
│   │   ├── llms-trait-singleton.php
│   │   ├── llms-trait-student-awards.php
│   │   └── llms-trait-user-engagement-type.php
│   └── widgets/
│       ├── class.llms.bbp.widget.course.forums.list.php
│       ├── class.llms.widget.course.progress.php
│       ├── class.llms.widget.course.syllabus.php
│       ├── class.llms.widget.php
│       ├── class.llms.widgets.php
│       └── index.php
├── index.php
├── languages/
│   ├── README.md
│   ├── countries-address-info.php
│   ├── countries.php
│   ├── currencies.php
│   ├── currency-symbols.php
│   └── states.php
├── lerna.json
├── libraries/
│   ├── README.md
│   └── index.php
├── lifterlms.php
├── package.json
├── packages/
│   ├── README.md
│   ├── brand/
│   │   ├── README.md
│   │   ├── package.json
│   │   └── sass/
│   │       ├── brand.scss
│   │       ├── colors.scss
│   │       └── typography.scss
│   ├── components/
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── button-group-control/
│   │       │   ├── index.js
│   │       │   └── test/
│   │       │       └── index.js
│   │       ├── copy-button/
│   │       │   └── index.js
│   │       ├── index.js
│   │       ├── post-select/
│   │       │   └── index.js
│   │       ├── search-control/
│   │       │   ├── base-search-control.js
│   │       │   ├── defaults.js
│   │       │   ├── index.js
│   │       │   ├── post-search-control.js
│   │       │   ├── styled-base-control.js
│   │       │   └── user-search-control.js
│   │       └── spinner/
│   │           ├── .eslintrc.js
│   │           ├── constants.js
│   │           ├── index.js
│   │           ├── styles.js
│   │           ├── test/
│   │           │   ├── __MOCKS__/
│   │           │   │   └── jquery.js
│   │           │   ├── __snapshots__/
│   │           │   │   ├── index.test.js.snap
│   │           │   │   └── utils.test.js.snap
│   │           │   ├── index.test.js
│   │           │   └── utils.test.js
│   │           └── utils.js
│   ├── dev/
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── .eslintrc.js
│   │   │   ├── cmds/
│   │   │   │   ├── changelog/
│   │   │   │   │   ├── add.js
│   │   │   │   │   ├── index.js
│   │   │   │   │   ├── list.js
│   │   │   │   │   ├── validate.js
│   │   │   │   │   ├── version.js
│   │   │   │   │   └── write.js
│   │   │   │   ├── docgen.js
│   │   │   │   ├── meta/
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── parse.js
│   │   │   │   ├── pot.js
│   │   │   │   ├── readme.js
│   │   │   │   ├── release/
│   │   │   │   │   ├── archive.js
│   │   │   │   │   ├── create.js
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── prepare.js
│   │   │   │   └── update-version.js
│   │   │   ├── index.js
│   │   │   └── utils/
│   │   │       ├── changelog-entry.js
│   │   │       ├── configs.js
│   │   │       ├── create-dist-file.js
│   │   │       ├── determine-version-increment.js
│   │   │       ├── exec-sync.js
│   │   │       ├── get-archive-filename.js
│   │   │       ├── get-changelog-entries.js
│   │   │       ├── get-changelog-for-version.js
│   │   │       ├── get-changelog-options.js
│   │   │       ├── get-current-version.js
│   │   │       ├── get-default.js
│   │   │       ├── get-next-version.js
│   │   │       ├── get-project-privacy.js
│   │   │       ├── get-project-slug.js
│   │   │       ├── index.js
│   │   │       ├── log-result.js
│   │   │       ├── pare-main-file-metadata.js
│   │   │       ├── parse-changelog-file.js
│   │   │       ├── parse-issue-string.js
│   │   │       ├── push-dist-file.js
│   │   │       ├── repo-links.js
│   │   │       └── validate-changelog.js
│   │   └── test/
│   │       └── utils/
│   │           ├── configs.test.js
│   │           ├── determine-version-increment.test.js
│   │           ├── exec-sync.test.js
│   │           ├── get-archive-filename.test.js
│   │           ├── get-changelog-for-version.test.js
│   │           ├── get-next-version.test.js
│   │           ├── get-project-privacy.test.js
│   │           ├── get-project-slug.test.js
│   │           ├── parse-changelog-file.test.js
│   │           ├── parse-issue-string.test.js
│   │           ├── repo-links.test.js
│   │           └── validate-changelog.test.js
│   ├── fontawesome/
│   │   ├── .eslintrc.js
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── bin/
│   │   │   ├── .eslintrc.js
│   │   │   ├── metadata.js
│   │   │   └── svg.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── components/
│   │       │   ├── icon-list.js
│   │       │   ├── icon-picker.js
│   │       │   └── icon.js
│   │       ├── fontawesome.scss
│   │       ├── index.js
│   │       └── metadata.json
│   ├── icons/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── docs/
│   │   │   ├── app.js
│   │   │   ├── generate.js
│   │   │   └── index.html
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.js
│   │       └── lifterlms.js
│   ├── llms-e2e-test-utils/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── .eslintrc.js
│   │       ├── activate-theme.js
│   │       ├── clear-blocks.js
│   │       ├── click-and-wait.js
│   │       ├── click-element-by-text.js
│   │       ├── click.js
│   │       ├── create-access-plan.js
│   │       ├── create-certificate.js
│   │       ├── create-coupon.js
│   │       ├── create-course.js
│   │       ├── create-engagement.js
│   │       ├── create-membership.js
│   │       ├── create-post.js
│   │       ├── create-user.js
│   │       ├── create-voucher.js
│   │       ├── dismiss-editor-welcome-guide.js
│   │       ├── enroll-student.js
│   │       ├── fill-field.js
│   │       ├── find-element-by-text.js
│   │       ├── get-all-blocks.js
│   │       ├── get-post-title.js
│   │       ├── get-wp-version.js
│   │       ├── highlight-node.js
│   │       ├── import-course.js
│   │       ├── index.js
│   │       ├── login-student.js
│   │       ├── logout-user.js
│   │       ├── open-sidebar-panel-tab.js
│   │       ├── publish-post.js
│   │       ├── register-student.js
│   │       ├── run-setup-wizard.js
│   │       ├── select2-select.js
│   │       ├── set-checkbox-setting.js
│   │       ├── set-select2-option.js
│   │       ├── toggle-open-registration.js
│   │       ├── toggle-sidebar-panel.js
│   │       ├── update-post.js
│   │       ├── visit-page.js
│   │       ├── visit-post-permalink.js
│   │       ├── visit-settings-page.js
│   │       └── wp-version-compare.js
│   ├── quill-wordcount-module/
│   │   ├── .eslintrc.js
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── create-container.js
│   │       ├── format-number.js
│   │       ├── get-counter-text-color.js
│   │       ├── index.js
│   │       ├── module.js
│   │       └── test/
│   │           ├── __snapshots__/
│   │           │   ├── create-container.test.js.snap
│   │           │   └── module.test.js.snap
│   │           ├── create-container.test.js
│   │           ├── format-number.test.js
│   │           ├── get-counter-text-color.js
│   │           ├── index.test.js
│   │           └── module.test.js
│   ├── scripts/
│   │   ├── .eslintrc.js
│   │   ├── .llmsdev.yml
│   │   ├── .npmrc
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── babel.config.js
│   │   ├── config/
│   │   │   ├── .eslintrc.js
│   │   │   ├── blocks-webpack.config.js
│   │   │   ├── import-resolver.js
│   │   │   ├── jest-unit.config.js
│   │   │   └── webpack.config.js
│   │   ├── e2e/
│   │   │   ├── bootstrap.js
│   │   │   ├── jest-puppeteer.config.js
│   │   │   ├── jest.config.js
│   │   │   └── sequencer.js
│   │   └── package.json
│   └── utils/
│       ├── .llmsdev.yml
│       ├── .npmrc
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── babel.config.js
│       ├── package.json
│       └── src/
│           ├── formatting/
│           │   ├── index.js
│           │   ├── test/
│           │   │   └── index.js
│           │   ├── trailing-slash-it.js
│           │   └── untrailing-slash-it.js
│           ├── index.js
│           └── url/
│               ├── get-admin-url.js
│               ├── index.js
│               └── test/
│                   └── get-admin-url.test.js
├── phpcs.xml
├── phpmd.xml
├── phpunit.xml.dist
├── sample-data/
│   ├── index.php
│   └── sample-course.json
├── src/
│   ├── blocks/
│   │   ├── access-plan-button/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── certificate-title/
│   │   │   ├── block.json
│   │   │   ├── edit.jsx
│   │   │   ├── icon.jsx
│   │   │   ├── index.jsx
│   │   │   └── save.jsx
│   │   ├── checkout/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-author/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-continue/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-meta-info/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-outline/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-prerequisites/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-reviews/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── course-syllabus/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── courses/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── login/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── memberships/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── my-account/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── my-achievements/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── navigation-link/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   ├── pricing-table/
│   │   │   ├── block.json
│   │   │   ├── icon.jsx
│   │   │   └── index.jsx
│   │   └── registration/
│   │       ├── block.json
│   │       ├── icon.jsx
│   │       └── index.jsx
│   ├── js/
│   │   ├── .eslintrc.js
│   │   ├── admin-addons.js
│   │   ├── admin-award-certificate.js
│   │   ├── admin-certificate-editor/
│   │   │   ├── document-settings.js
│   │   │   ├── edit-certificate.js
│   │   │   ├── editor.js
│   │   │   ├── i18n.js
│   │   │   ├── index.js
│   │   │   ├── merge-codes.js
│   │   │   ├── migrate.js
│   │   │   ├── modify-blocks.js
│   │   │   ├── notices.js
│   │   │   ├── plugin/
│   │   │   │   ├── background-control.js
│   │   │   │   ├── margins-control.js
│   │   │   │   ├── orientation-control.js
│   │   │   │   ├── sequential-id-control.js
│   │   │   │   ├── size-control.js
│   │   │   │   └── title-control.js
│   │   │   ├── post-status-info/
│   │   │   │   ├── award-button.js
│   │   │   │   ├── award-check.js
│   │   │   │   ├── index.js
│   │   │   │   ├── reset-template-button.js
│   │   │   │   └── reset-template-check.js
│   │   │   └── user-settings.js
│   │   ├── admin-certificate-editor.js
│   │   ├── admin-elementor-editor.js
│   │   ├── admin-media-protection-block-protect.js
│   │   ├── components.js
│   │   ├── icons.js
│   │   ├── quill-wordcount.js
│   │   ├── spinner.js
│   │   ├── util/
│   │   │   ├── README.md
│   │   │   ├── award-certificate-button/
│   │   │   │   ├── create.js
│   │   │   │   ├── index.js
│   │   │   │   ├── message.js
│   │   │   │   ├── test/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.js.snap
│   │   │   │   │   └── index.js
│   │   │   │   └── urls.js
│   │   │   ├── edit-certificate-title.js
│   │   │   └── index.js
│   │   └── utils.js
│   └── scss/
│       ├── admin-addons.scss
│       └── fontawesome.scss
├── templates/
│   ├── achievements/
│   │   ├── loop.php
│   │   └── template.php
│   ├── admin/
│   │   ├── analytics/
│   │   │   └── analytics.php
│   │   ├── notices/
│   │   │   └── staging.php
│   │   ├── post-types/
│   │   │   ├── order-transactions.php
│   │   │   └── students.php
│   │   ├── reporting/
│   │   │   ├── nav-filters.php
│   │   │   ├── reporting.php
│   │   │   └── tabs/
│   │   │       ├── courses/
│   │   │       │   ├── course.php
│   │   │       │   ├── overview.php
│   │   │       │   └── students.php
│   │   │       ├── memberships/
│   │   │       │   ├── membership.php
│   │   │       │   ├── overview.php
│   │   │       │   └── students.php
│   │   │       ├── quizzes/
│   │   │       │   ├── attempt.php
│   │   │       │   ├── attempts.php
│   │   │       │   ├── non-attempts.php
│   │   │       │   ├── overview.php
│   │   │       │   └── quiz.php
│   │   │       ├── students/
│   │   │       │   ├── achievements.php
│   │   │       │   ├── certificates.php
│   │   │       │   ├── courses-course.php
│   │   │       │   ├── courses.php
│   │   │       │   ├── information.php
│   │   │       │   ├── memberships.php
│   │   │       │   ├── quiz_attempts.php
│   │   │       │   ├── student.php
│   │   │       │   └── students.php
│   │   │       └── widgets.php
│   │   └── user-edit.php
│   ├── archive-course.php
│   ├── archive-llms_membership.php
│   ├── block-templates/
│   │   ├── archive-course.html
│   │   ├── archive-llms_membership.html
│   │   ├── single-no-access.html
│   │   ├── taxonomy-course_cat.html
│   │   ├── taxonomy-course_difficulty.html
│   │   ├── taxonomy-course_tag.html
│   │   ├── taxonomy-course_track.html
│   │   ├── taxonomy-membership_cat.html
│   │   └── taxonomy-membership_tag.html
│   ├── certificates/
│   │   ├── actions.php
│   │   ├── content-legacy.php
│   │   ├── content.php
│   │   ├── dynamic-styles.php
│   │   ├── footer.php
│   │   ├── header.php
│   │   ├── loop.php
│   │   ├── preview.php
│   │   └── template.php
│   ├── checkout/
│   │   ├── form-checkout.php
│   │   ├── form-confirm-payment.php
│   │   ├── form-coupon.php
│   │   ├── form-gateways.php
│   │   ├── form-summary.php
│   │   └── form-switch-source.php
│   ├── content-certificate.php
│   ├── content-no-access-after.php
│   ├── content-no-access-before.php
│   ├── content-no-access.php
│   ├── content-single-course-after.php
│   ├── content-single-course-before.php
│   ├── content-single-lesson-after.php
│   ├── content-single-lesson-before.php
│   ├── content-single-membership-after.php
│   ├── content-single-membership-before.php
│   ├── content-single-question.php
│   ├── content-single-quiz-after.php
│   ├── content-single-quiz-before.php
│   ├── course/
│   │   ├── audio.php
│   │   ├── author.php
│   │   ├── categories.php
│   │   ├── complete-lesson-link.php
│   │   ├── difficulty.php
│   │   ├── favorite.php
│   │   ├── full-description.php
│   │   ├── length.php
│   │   ├── lesson-count.php
│   │   ├── lesson-navigation.php
│   │   ├── lesson-preview.php
│   │   ├── meta-wrapper-end.php
│   │   ├── meta-wrapper-start.php
│   │   ├── outline-list-small.php
│   │   ├── parent-course.php
│   │   ├── prerequisites.php
│   │   ├── progress.php
│   │   ├── short-description.php
│   │   ├── syllabus.php
│   │   ├── tags.php
│   │   ├── title.php
│   │   ├── tracks.php
│   │   └── video.php
│   ├── emails/
│   │   ├── footer.php
│   │   ├── header.php
│   │   ├── reset-password.php
│   │   └── template.php
│   ├── global/
│   │   ├── form-login.php
│   │   ├── form-registration.php
│   │   ├── sidebar.php
│   │   ├── wrapper-end.php
│   │   └── wrapper-start.php
│   ├── lesson/
│   │   ├── audio.php
│   │   └── video.php
│   ├── loop/
│   │   ├── author.php
│   │   ├── content.php
│   │   ├── enroll-date.php
│   │   ├── enroll-status.php
│   │   ├── featured-image.php
│   │   ├── featured-pricing.php
│   │   ├── loop-end.php
│   │   ├── loop-start.php
│   │   ├── none-found.php
│   │   └── pagination.php
│   ├── loop-main.php
│   ├── loop.php
│   ├── membership/
│   │   ├── audio.php
│   │   ├── full-description.php
│   │   ├── instructors.php
│   │   ├── price.php
│   │   ├── title.php
│   │   └── video.php
│   ├── myaccount/
│   │   ├── dashboard-section.php
│   │   ├── dashboard.php
│   │   ├── form-edit-account.php
│   │   ├── form-lost-password.php
│   │   ├── form-redeem-voucher.php
│   │   ├── header.php
│   │   ├── my-favorites.php
│   │   ├── my-grades-single-table.php
│   │   ├── my-grades-single.php
│   │   ├── my-grades.php
│   │   ├── my-notifications.php
│   │   ├── my-orders.php
│   │   ├── navigation.php
│   │   ├── view-order-actions.php
│   │   ├── view-order-information.php
│   │   ├── view-order-transactions.php
│   │   └── view-order.php
│   ├── notices/
│   │   ├── debug.php
│   │   ├── error.php
│   │   ├── notice.php
│   │   └── success.php
│   ├── notifications/
│   │   └── basic.php
│   ├── product/
│   │   ├── access-plan-button.php
│   │   ├── access-plan-description.php
│   │   ├── access-plan-feature.php
│   │   ├── access-plan-pricing.php
│   │   ├── access-plan-restrictions.php
│   │   ├── access-plan-title.php
│   │   ├── access-plan-trial.php
│   │   ├── access-plan.php
│   │   ├── free-enroll-form.php
│   │   ├── not-purchasable.php
│   │   └── pricing-table.php
│   ├── quiz/
│   │   ├── meta-information.php
│   │   ├── questions/
│   │   │   ├── content-choice.php
│   │   │   ├── content-picture_choice.php
│   │   │   ├── content-true_false.php
│   │   │   ├── description.php
│   │   │   ├── image.php
│   │   │   ├── video.php
│   │   │   ├── wrapper-end.php
│   │   │   └── wrapper-start.php
│   │   ├── quiz-wrapper-end.php
│   │   ├── quiz-wrapper-start.php
│   │   ├── results-attempt-questions-list.php
│   │   ├── results-attempt.php
│   │   ├── results.php
│   │   ├── return-to-lesson.php
│   │   └── start-button.php
│   ├── shared/
│   │   └── instructors.php
│   ├── single-certificate.php
│   ├── single-lesson-focus.php
│   ├── single-no-access.php
│   ├── taxonomy-course_cat.php
│   ├── taxonomy-course_difficulty.php
│   ├── taxonomy-course_tag.php
│   ├── taxonomy-course_track.php
│   ├── taxonomy-membership_cat.php
│   └── taxonomy-membership_tag.php
├── tests/
│   ├── assets/
│   │   ├── example-style-1.css
│   │   ├── example-style-2.css
│   │   ├── example-style.css
│   │   ├── import-error.json
│   │   ├── import-fake-generator.json
│   │   ├── import-with-prerequisites.json
│   │   ├── import-with-quiz.json
│   │   ├── import-with-restrictions.json
│   │   ├── lifterlms-en_US-cd71ad734c92669051f6fd28eb90dfd4.json
│   │   ├── lifterlms-en_US.mo
│   │   ├── lifterlms-en_US.po
│   │   └── lifterlms-mock-addon.php
│   ├── bin/
│   │   └── setup-e2e.sh
│   ├── e2e/
│   │   ├── README.md
│   │   └── tests/
│   │       ├── activate/
│   │       │   └── bootstrap.test.js
│   │       ├── checkout/
│   │       │   └── coupon.test.js
│   │       ├── page-restrictions/
│   │       │   ├── course.test.js
│   │       │   └── sitewide-membership.test.js
│   │       ├── settings/
│   │       │   └── copy-prevention.test.js
│   │       ├── student/
│   │       │   ├── __snapshots__/
│   │       │   │   ├── open-registration.test.js.snap
│   │       │   │   └── voucher.test.js.snap
│   │       │   ├── login.test.js
│   │       │   ├── open-registration.test.js
│   │       │   └── voucher.test.js
│   │       └── view-manager/
│   │           ├── __snapshots__/
│   │           │   └── view-manager.test.js.snap
│   │           └── view-manager.test.js
│   └── phpunit/
│       ├── README.md
│       ├── bootstrap.php
│       ├── framework/
│       │   ├── class-llms-admin-tool-test-case.php
│       │   ├── class-llms-notification-test-case.php
│       │   ├── class-llms-payment-gateway-mock.php
│       │   ├── class-llms-post-model-unit-test-case.php
│       │   ├── class-llms-post-type-metabox-test-case.php
│       │   ├── class-llms-settings-page-test-case.php
│       │   ├── class-llms-shortcode-test-case.php
│       │   └── class-llms-unit-test-case.php
│       └── unit-tests/
│           ├── abstracts/
│           │   ├── class-llms-test-abstract-admin-metabox.php
│           │   ├── class-llms-test-abstract-admin-tool.php
│           │   ├── class-llms-test-abstract-database-query.php
│           │   ├── class-llms-test-abstract-exportable-abmin-table.php
│           │   ├── class-llms-test-abstract-generator-posts.php
│           │   ├── class-llms-test-abstract-integration.php
│           │   ├── class-llms-test-abstract-notification-view.php
│           │   ├── class-llms-test-abstract-options-data.php
│           │   ├── class-llms-test-abstract-payment-gateway.php
│           │   ├── class-llms-test-abstract-post-model.php
│           │   ├── class-llms-test-abstract-posts-query.php
│           │   ├── class-llms-test-abstract-query.php
│           │   ├── class-llms-test-abstract-session-data.php
│           │   └── class-llms-test-abstract-session-database-handler.php
│           ├── admin/
│           │   ├── class-llms-test-admin-assets.php
│           │   ├── class-llms-test-admin-builder.php
│           │   ├── class-llms-test-admin-import.php
│           │   ├── class-llms-test-admin-menus.php
│           │   ├── class-llms-test-admin-notices.php
│           │   ├── class-llms-test-admin-page-status.php
│           │   ├── class-llms-test-admin-post-types.php
│           │   ├── class-llms-test-admin-profile.php
│           │   ├── class-llms-test-admin-review.php
│           │   ├── class-llms-test-admin-settings.php
│           │   ├── class-llms-test-admin-setup-wizard.php
│           │   ├── class-llms-test-admin-users-table.php
│           │   ├── class-llms-test-export-api.php
│           │   ├── class-llms-test-sendwp.php
│           │   ├── post-types/
│           │   │   ├── class-llms-test-llms-admin-meta-boxes.php
│           │   │   ├── meta-boxes/
│           │   │   │   ├── class-llms-test-meta-box-access.php
│           │   │   │   ├── class-llms-test-meta-box-achievement-sync.php
│           │   │   │   ├── class-llms-test-meta-box-achievement.php
│           │   │   │   ├── class-llms-test-meta-box-award-engagement-submit.php
│           │   │   │   ├── class-llms-test-meta-box-certificate-sync.php
│           │   │   │   ├── class-llms-test-meta-box-certificate.php
│           │   │   │   ├── class-llms-test-meta-box-lesson.php
│           │   │   │   ├── class-llms-test-meta-box-order-details.php
│           │   │   │   ├── class-llms-test-meta-box-order-enrollment.php
│           │   │   │   ├── class-llms-test-meta-box-order-submit.php
│           │   │   │   └── fields/
│           │   │   │       └── class-llms-test-meta-box-textarea-tags.php
│           │   │   └── post-tables/
│           │   │       └── class-llms-admin-post-table-certificates.php
│           │   ├── reporting/
│           │   │   ├── __snapshots__/
│           │   │   │   ├── admin-reporting-output_widget-test-a.txt
│           │   │   │   ├── admin-reporting-output_widget-test-b.txt
│           │   │   │   ├── admin-reporting-output_widget-test-c.txt
│           │   │   │   ├── admin-reporting-output_widget-test-d.txt
│           │   │   │   ├── admin-reporting-output_widget-test-e.txt
│           │   │   │   ├── admin-reporting-output_widget-test-f.txt
│           │   │   │   ├── admin-reporting-output_widget-test-g.txt
│           │   │   │   └── admin-reporting-output_widget-test-h.txt
│           │   │   └── class-llms-test-admin-reporting.php
│           │   ├── settings/
│           │   │   ├── class-llms-test-settings-accounts.php
│           │   │   ├── class-llms-test-settings-engagements.php
│           │   │   └── class-llms-test-settings-page.php
│           │   └── tools/
│           │       ├── class-llms-test-admin-tool-batch-eraser.php
│           │       ├── class-llms-test-admin-tool-clear-sessions.php
│           │       ├── class-llms-test-admin-tool-install-forms.php
│           │       ├── class-llms-test-admin-tool-limited-billing-order-locator.php
│           │       ├── class-llms-test-admin-tool-recurring-payment-rescheduler.php
│           │       ├── class-llms-test-admin-tool-reset-automatic-payments.php
│           │       └── class-llms-test-admin-tool-wipe-legacy-account-options.php
│           ├── ajax/
│           │   ├── class-llms-test-ajax-handler-coupons.php
│           │   └── class-llms-test-ajax-handler-quizzes.php
│           ├── class-llms-test-admin-media-protection-attachment-settings.php
│           ├── class-llms-test-ajax-handler.php
│           ├── class-llms-test-assets.php
│           ├── class-llms-test-awards-query.php
│           ├── class-llms-test-block-library.php
│           ├── class-llms-test-block-templates.php
│           ├── class-llms-test-blocks.php
│           ├── class-llms-test-cache-helper.php
│           ├── class-llms-test-certificates.php
│           ├── class-llms-test-cli.php
│           ├── class-llms-test-comments.php
│           ├── class-llms-test-db-upgrader.php
│           ├── class-llms-test-engagement-handler.php
│           ├── class-llms-test-engagements.php
│           ├── class-llms-test-events-core.php
│           ├── class-llms-test-events-query.php
│           ├── class-llms-test-events.php
│           ├── class-llms-test-frontend-assets.php
│           ├── class-llms-test-functions-access.php
│           ├── class-llms-test-functions-privacy.php
│           ├── class-llms-test-functions-quiz.php
│           ├── class-llms-test-gateway-manual.php
│           ├── class-llms-test-generator-courses.php
│           ├── class-llms-test-generator.php
│           ├── class-llms-test-grades.php
│           ├── class-llms-test-hasher.php
│           ├── class-llms-test-helper.php
│           ├── class-llms-test-https.php
│           ├── class-llms-test-install.php
│           ├── class-llms-test-integrations.php
│           ├── class-llms-test-llms-dom-document.php
│           ├── class-llms-test-main-class.php
│           ├── class-llms-test-mime-type-extractor.php
│           ├── class-llms-test-order-generator.php
│           ├── class-llms-test-payment-gateway-integrations.php
│           ├── class-llms-test-payment-gateways.php
│           ├── class-llms-test-playnice.php
│           ├── class-llms-test-post-instructors.php
│           ├── class-llms-test-post-relationships.php
│           ├── class-llms-test-post-types.php
│           ├── class-llms-test-prevent-concurrent-logins.php
│           ├── class-llms-test-query.php
│           ├── class-llms-test-quiz-attempt-query.php
│           ├── class-llms-test-rest-fields.php
│           ├── class-llms-test-rest.php
│           ├── class-llms-test-review.php
│           ├── class-llms-test-roles.php
│           ├── class-llms-test-session.php
│           ├── class-llms-test-sessions.php
│           ├── class-llms-test-shortcodes.php
│           ├── class-llms-test-site.php
│           ├── class-llms-test-staging.php
│           ├── class-llms-test-student-query.php
│           ├── class-llms-test-template-functions.php
│           ├── class-llms-test-template-loader.php
│           ├── class-llms-test-user-postmeta-query.php
│           ├── class-llms-test-view-manager.php
│           ├── controllers/
│           │   ├── class-llms-test-conroller-quizzes.php
│           │   ├── class-llms-test-controller-account.php
│           │   ├── class-llms-test-controller-achievements.php
│           │   ├── class-llms-test-controller-awards.php
│           │   ├── class-llms-test-controller-certificates.php
│           │   ├── class-llms-test-controller-checkout.php
│           │   ├── class-llms-test-controller-lesson-progression.php
│           │   ├── class-llms-test-controller-login.php
│           │   ├── class-llms-test-controller-orders.php
│           │   └── class-llms-test-controller-registration.php
│           ├── forms/
│           │   ├── class-llms-test-form-field.php
│           │   ├── class-llms-test-form-handler.php
│           │   ├── class-llms-test-form-post-type.php
│           │   ├── class-llms-test-form-templates.php
│           │   ├── class-llms-test-form-validator.php
│           │   ├── class-llms-test-forms-admin-bar.php
│           │   ├── class-llms-test-forms-classic-editor.php
│           │   ├── class-llms-test-forms-data.php
│           │   ├── class-llms-test-forms-dynamic-fields.php
│           │   ├── class-llms-test-forms-unsupported-versions.php
│           │   └── class-llms-test-forms.php
│           ├── functions/
│           │   ├── class-llms-test-functions-access-plans.php
│           │   ├── class-llms-test-functions-admin.php
│           │   ├── class-llms-test-functions-certificates.php
│           │   ├── class-llms-test-functions-conditional-tags.php
│           │   ├── class-llms-test-functions-content.php
│           │   ├── class-llms-test-functions-core.php
│           │   ├── class-llms-test-functions-currency.php
│           │   ├── class-llms-test-functions-deprecated.php
│           │   ├── class-llms-test-functions-forms.php
│           │   ├── class-llms-test-functions-l10n.php
│           │   ├── class-llms-test-functions-locale.php
│           │   ├── class-llms-test-functions-logs.php
│           │   ├── class-llms-test-functions-options.php
│           │   ├── class-llms-test-functions-order.php
│           │   ├── class-llms-test-functions-page.php
│           │   ├── class-llms-test-functions-person.php
│           │   ├── class-llms-test-functions-progression.php
│           │   ├── class-llms-test-functions-template.php
│           │   ├── class-llms-test-functions-templates-certificates.php
│           │   ├── class-llms-test-functions-templates-dasbhoard.php
│           │   ├── class-llms-test-functions-templates-loop.php
│           │   ├── class-llms-test-functions-templates-pricing-table.php
│           │   ├── class-llms-test-functions-templates-vier-order.php
│           │   ├── class-llms-test-functions-updates.php
│           │   ├── class-llms-test-functions-user-information-fields.php
│           │   ├── class-llms-test-functions-user-postmeta.php
│           │   ├── class-llms-test-template-functions.php
│           │   └── updates/
│           │       ├── class-llms-test-functions-updates-400.php
│           │       ├── class-llms-test-functions-updates-4150.php
│           │       ├── class-llms-test-functions-updates-450.php
│           │       ├── class-llms-test-functions-updates-500.php
│           │       ├── class-llms-test-functions-updates-520.php
│           │       ├── class-llms-test-functions-updates-600.php
│           │       ├── class-llms-test-functions-updates-6100.php
│           │       └── class-llms-test-functions-updates-630.php
│           ├── functions-templates/
│           │   ├── class-llms-test-functions-templates-courses.php
│           │   ├── class-llms-test-functions-templates-memberships.php
│           │   └── class-llms-test-functions-templates-pricing-table.php
│           ├── integrations/
│           │   ├── class-llms-test-integration-bbpress.php
│           │   └── class-llms-test-integration-buddypress.php
│           ├── models/
│           │   ├── class-llms-test-event.php
│           │   ├── class-llms-test-instructor.php
│           │   ├── class-llms-test-model-llms-access-plan.php
│           │   ├── class-llms-test-model-llms-add-on.php
│           │   ├── class-llms-test-model-llms-coupon.php
│           │   ├── class-llms-test-model-llms-course.php
│           │   ├── class-llms-test-model-llms-lesson.php
│           │   ├── class-llms-test-model-llms-membership.php
│           │   ├── class-llms-test-model-llms-order.php
│           │   ├── class-llms-test-model-llms-product.php
│           │   ├── class-llms-test-model-llms-question.php
│           │   ├── class-llms-test-model-llms-quiz-attempt.php
│           │   ├── class-llms-test-model-llms-quiz.php
│           │   ├── class-llms-test-model-llms-section.php
│           │   ├── class-llms-test-model-llms-student-quizzes.php
│           │   ├── class-llms-test-model-llms-student.php
│           │   ├── class-llms-test-model-llms-transaction.php
│           │   ├── class-llms-test-model-llms-user-achievement.php
│           │   └── class-llms-test-model-llms-user-certificate.php
│           ├── notifications/
│           │   ├── class-llms-test-notification-achievement-earned.php
│           │   ├── class-llms-test-notification-certificate-earned.php
│           │   ├── class-llms-test-notifications-query.php
│           │   ├── class-llms-test-notifications.php
│           │   └── controllers/
│           │       └── class-llms-test-notification-controller-upcoming-payment-reminder.php
│           ├── processors/
│           │   ├── class-llms-test-processor-awarded-achievements-bulk-sync.php
│           │   ├── class-llms-test-processor-awarded-certificates-bulk-sync.php
│           │   ├── class-llms-test-processor-course-data.php
│           │   └── class-llms-test-processors.php
│           ├── shortcodes/
│           │   ├── class-llms-test-shortcode-checkout.php
│           │   ├── class-llms-test-shortcode-course-progress.php
│           │   ├── class-llms-test-shortcode-hide-content.php
│           │   └── class-llms-test-shortcode-user-info.php
│           ├── tables/
│           │   ├── class-llms-test-table-course-students.php
│           │   ├── class-llms-test-table-quizzes.php
│           │   └── class-llms-test-table-students.php
│           ├── theme-support/
│           │   ├── class-llms-test-theme-support.php
│           │   ├── class-llms-test-twenty-twenty-one.php
│           │   ├── class-llms-test-twenty-twenty-two.php
│           │   └── class-llms-test-twenty-twenty.php
│           ├── traits/
│           │   ├── llms-test-trait-audio-video-embed.php
│           │   ├── llms-test-trait-award-default-images.php
│           │   ├── llms-test-trait-award-templates-post-list-table.php
│           │   ├── llms-test-trait-sales-page.php
│           │   ├── llms-test-trait-singleton.php
│           │   ├── llms-test-trait-student-awards.php
│           │   └── llms-test-trait-user-engagement-type.php
│           └── user/
│               ├── class-llms-test-abstract-user-data.php
│               ├── class-llms-test-person-handler.php
│               ├── class-llms-test-student-quizzes.php
│               ├── class-llms-test-student.php
│               └── class-llms-test-user-permissions.php
├── uninstall.php
└── webpack.config.js
Download .txt
Showing preview only (868K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (7986 symbols across 862 files)

FILE: assets/js/app/llms-donut.js
  function Donut (line 25) | function Donut(options) {
  function draw (line 74) | function draw( $el ) {

FILE: assets/js/app/llms-tracking.js
  function init (line 33) | function init() {
  function onBeforeUnload (line 161) | function onBeforeUnload( e ) {
  function onUnload (line 173) | function onUnload( e ) {
  function onVisibilityChange (line 185) | function onVisibilityChange( e ) {

FILE: assets/js/builder/Controllers/Construct.js
  function get (line 31) | function get( type, name, data, options ) {

FILE: assets/js/builder/Controllers/Sync.js
  function init (line 27) | function init() {
  function add_error_msg (line 77) | function add_error_msg( data, err ) {
  function check_for_changes (line 100) | function check_for_changes() {
  function do_ajax_save (line 121) | function do_ajax_save() {
  function get_changed_attributes (line 199) | function get_changed_attributes( model ) {
  function get_changes_to_object (line 258) | function get_changes_to_object( object ) {
  function has_temp_id (line 308) | function has_temp_id( model ) {
  function maybe_restart_tracking (line 324) | function maybe_restart_tracking( model, data ) {
  function process_removals (line 358) | function process_removals( data ) {
  function process_object_updates (line 410) | function process_object_updates( data, type, parent, main_data ) {
  function process_updates (line 520) | function process_updates( data ) {

FILE: assets/js/builder/Views/SettingsFields.js
  function option_html (line 255) | function option_html( label, val ) {

FILE: assets/js/builder/main.js
  function value_compare (line 46) | function value_compare( expected, actual ) {

FILE: assets/js/builder/vendor/almond.js
  function hasProp (line 20) | function hasProp(obj, prop) {
  function normalize (line 32) | function normalize(name, baseName) {
  function makeRequire (line 142) | function makeRequire(relName, forceSync) {
  function makeNormalize (line 159) | function makeNormalize(relName) {
  function makeLoad (line 165) | function makeLoad(depName) {
  function callDep (line 171) | function callDep(name) {
  function splitPrefix (line 188) | function splitPrefix(name) {
  function makeRelParts (line 200) | function makeRelParts(relName) {
  function makeConfig (line 248) | function makeConfig(name) {

FILE: assets/js/builder/vendor/backbone.collectionView.js
  function _normalizeOptionDeclarations (line 1180) | function _normalizeOptionDeclarations( optionDeclarations ) {

FILE: assets/js/builder/vendor/wp-hooks.js
  function e (line 11) | function e(t){if(r[t])return r[t].exports;var o=r[t]={i:t,l:!1,exports:{...

FILE: assets/js/llms-admin-forms.js
  function createNewButton (line 27) | function createNewButton() {
  function createHelpIcon (line 47) | function createHelpIcon() {
  function createHelpNode (line 85) | function createHelpNode() {
  function toggleHelpNode (line 105) | function toggleHelpNode() {
  function init (line 127) | function init() {

FILE: assets/js/llms-admin-tables.js
  function activate_button (line 191) | function activate_button() {
  function debounce (line 358) | function debounce( fn, delay ) {

FILE: assets/js/llms-admin-wizard.js
  function getSelectedImportCount (line 27) | function getSelectedImportCount() {

FILE: assets/js/llms-admin.js
  function map_data (line 131) | function map_data( items ) {
  function format_item (line 153) | function format_item( item ) {
  function appendInput (line 293) | function appendInput( name, value ) {

FILE: assets/js/llms-ajax.js
  function Ajax (line 1) | function Ajax ( type, data, cache ) {

FILE: assets/js/llms-focus-mode.js
  function init (line 14) | function init() {

FILE: assets/js/llms-form-checkout.js
  function runHandler (line 507) | function runHandler({ handler, data }) {

FILE: assets/js/llms-metabox-voucher.js
  function bindDeleteVoucherCode (line 104) | function bindDeleteVoucherCode() {
  function randomizeCode (line 128) | function randomizeCode() {
  function check_voucher_duplicate (line 148) | function check_voucher_duplicate() {
  function get_codes_from_inputs (line 168) | function get_codes_from_inputs() {
  function llms_on_voucher_duplicate (line 179) | function llms_on_voucher_duplicate( results ) {

FILE: assets/js/llms-notifications.js
  function bind_events (line 20) | function bind_events() {

FILE: assets/js/llms-quiz-attempt-review.js
  function bind (line 24) | function bind() {
  function setup_fields (line 47) | function setup_fields() {

FILE: assets/js/partials/_metabox-field-repeater.js
  function replace_attr (line 364) | function replace_attr( $el, attr ) {

FILE: assets/js/private/llms-metaboxes.js
  function make_editable (line 330) | function make_editable( $field ) {
  function toggle_header_row (line 517) | function toggle_header_row() {
  function get_course_ids (line 535) | function get_course_ids() {
  function llmsShouldFixTinyMCEEditor (line 887) | function llmsShouldFixTinyMCEEditor( key ) {

FILE: assets/js/vendor/js.cookie.js
  function extend (line 27) | function extend () {
  function decode (line 39) | function decode (s) {
  function init (line 43) | function init (converter) {

FILE: assets/vendor/datetimepicker/jquery.datetimepicker.full.js
  function getCurrentValue (line 2241) | function getCurrentValue() {
  function setMask (line 2272) | function setMask(options) {
  function HighlightedDate (line 2604) | function HighlightedDate(date, desc, style) {
  function handler (line 2718) | function handler(event) {
  function nullLowestDelta (line 2831) | function nullLowestDelta() {
  function shouldAdjustOldDeltas (line 2835) | function shouldAdjustOldDeltas(orgEvent, absDelta) {

FILE: assets/vendor/izimodal/iziModal.js
  function whichAnimationEvent (line 38) | function whichAnimationEvent(){
  function isIE (line 54) | function isIE(version) {
  function clearValue (line 63) | function clearValue(value){
  function opened (line 313) | function opened(){
  function bindEvents (line 325) | function bindEvents(){
  function closed (line 582) | function closed(){

FILE: assets/vendor/quill/quill.js
  class c (line 2) | class c extends r.BlockBlot{cache={};delta(){return null==this.cache.del...
    method delta (line 2) | delta(){return null==this.cache.delta&&(this.cache.delta=h(this)),this...
    method deleteAt (line 2) | deleteAt(t,e){super.deleteAt(t,e),this.cache={}}
    method formatAt (line 2) | formatAt(t,e,n,i){e<=0||(this.scroll.query(n,r.Scope.BLOCK)?t+e===this...
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return super.insertAt(t,e,n),void(this.cach...
    method insertBefore (line 2) | insertBefore(t,e){const{head:n}=this.children;super.insertBefore(t,e),...
    method length (line 2) | length(){return null==this.cache.length&&(this.cache.length=super.leng...
    method moveChildren (line 2) | moveChildren(t,e){super.moveChildren(t,e),this.cache={}}
    method optimize (line 2) | optimize(t){super.optimize(t),this.cache={}}
    method path (line 2) | path(t){return super.path(t,!0)}
    method removeChild (line 2) | removeChild(t){super.removeChild(t),this.cache={}}
    method split (line 2) | split(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1]...
  class u (line 2) | class u extends r.EmbedBlot{attach(){super.attach(),this.attributes=new ...
    method attach (line 2) | attach(){super.attach(),this.attributes=new r.AttributorStore(this.dom...
    method delta (line 2) | delta(){return(new(s())).insert(this.value(),{...this.formats(),...thi...
    method format (line 2) | format(t,e){const n=this.scroll.query(t,r.Scope.BLOCK_ATTRIBUTE);null!...
    method formatAt (line 2) | formatAt(t,e,n,r){this.format(n,r)}
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return void super.insertAt(t,e,n);const r=e...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("spellc...
    method code (line 2) | code(t,e){return this.children.map((t=>t.length()<=1?"":t.domNode.inne...
    method html (line 2) | html(t,e){return`<pre>\n${(0,l.X)(this.code(t,e))}\n</pre>`}
  function h (line 2) | function h(t){let e=!(arguments.length>1&&void 0!==arguments[1])||argume...
    method register (line 2) | static register(){c.Ay.register(u)}
    method constructor (line 2) | constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.op...
    method registerEmbed (line 2) | static registerEmbed(t,e){this.handlers[t]=e}
    method unregisterEmbed (line 2) | static unregisterEmbed(t){delete this.handlers[t]}
    method getHandler (line 2) | static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`n...
    method insert (line 2) | insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n....
    method delete (line 2) | delete(t){return t<=0?this:this.push({delete:t})}
    method retain (line 2) | retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t}...
    method push (line 2) | push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==type...
    method chop (line 2) | chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof ...
    method filter (line 2) | filter(t){return this.ops.filter(t)}
    method forEach (line 2) | forEach(t){this.ops.forEach(t)}
    method map (line 2) | map(t){return this.ops.map(t)}
    method partition (line 2) | partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(...
    method reduce (line 2) | reduce(t,e){return this.ops.reduce(t,e)}
    method changeLength (line 2) | changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(...
    method length (line 2) | length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}
    method slice (line 2) | slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i<e...
    method compose (line 2) | compose(t){const e=new a.default(this.ops),n=new a.default(t.ops),r=[]...
    method concat (line 2) | concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.pu...
    method diff (line 2) | diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e....
    method eachLine (line 2) | eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for...
    method invert (line 2) | invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.dele...
    method transform (line 2) | transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPos...
    method transformPosition (line 2) | transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=...
    method formats (line 2) | static formats(t){return this.tagName.indexOf(t.tagName)+1}
  function d (line 2) | function d(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[...
  class i (line 2) | class i extends r.EmbedBlot{static value(){}optimize(){(this.prev||this....
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  class i (line 2) | class i extends r.ContainerBlot{}
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  class s (line 2) | class s extends r.EmbedBlot{static blotName="cursor";static className="q...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  class o (line 2) | class o extends r.EmbedBlot{constructor(t,e){super(t,e),this.contentNode...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  class o (line 2) | class o extends r.InlineBlot{static allowedChildren=[o,i.A,r.EmbedBlot,s...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  class i (line 2) | class i extends r.TextBlot{}
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  function s (line 2) | function s(t){return t.replace(/[&<>"']/g,(t=>({"&":"&amp;","<":"&lt;","...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  function p (line 2) | function p(t){return t instanceof i.Ay||t instanceof i.zo}
  function g (line 2) | function g(t){return"function"==typeof t.updateContent}
  class m (line 2) | class m extends u.ScrollBlot{static blotName="scroll";static className="...
    method constructor (line 2) | constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.bat...
    method batchStart (line 2) | batchStart(){Array.isArray(this.batch)||(this.batch=[])}
    method batchEnd (line 2) | batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this...
    method emitMount (line 2) | emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}
    method emitUnmount (line 2) | emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}
    method emitEmbedUpdate (line 2) | emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,...
    method deleteAt (line 2) | deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.dele...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}
    method insertAt (line 2) | insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.quer...
    method insertBefore (line 2) | insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=th...
    method insertContents (line 2) | insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d()...
    method isEnabled (line 2) | isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}
    method leaf (line 2) | leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;...
    method line (line 2) | line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}
    method lines (line 2) | lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0...
    method optimize (line 2) | optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method path (line 2) | path(t){return super.path(t).slice(1)}
    method remove (line 2) | remove(){}
    method update (line 2) | update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this...
    method updateEmbedAt (line 2) | updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t...
    method handleDragStart (line 2) | handleDragStart(t){t.preventDefault()}
    method deltaToRenderBlocks (line 2) | deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>...
    method createBlock (line 2) | createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e...
    method create (line 2) | static create(t){const e=super.create();return e.setAttribute("data-li...
    method formats (line 2) | static formats(t){return t.getAttribute("data-list")||void 0}
    method register (line 2) | static register(){p.Ay.register(g)}
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("spa...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
  function b (line 2) | function b(t,e,n){n.reduce(((e,n)=>{const r=h.Op.length(n);let s=n.attri...
    method constructor (line 2) | constructor(){this.head=null,this.tail=null,this.length=0}
    method append (line 2) | append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.sli...
    method at (line 2) | at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}
    method contains (line 2) | contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return...
    method indexOf (line 2) | indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)ret...
    method insertBefore (line 2) | insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e....
    method offset (line 2) | offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.le...
    method remove (line 2) | remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=...
    method iterator (line 2) | iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}
    method find (line 2) | find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.leng...
    method forEach (line 2) | forEach(t){const e=this.iterator();let n=e();for(;n;)t(n),n=e()}
    method forEachAt (line 2) | forEachAt(t,e,n){if(e<=0)return;const[r,i]=this.find(t);let s=t-i;cons...
    method map (line 2) | map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}
    method reduce (line 2) | reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();r...
  class N (line 2) | class N extends x.A{static DEFAULTS={delay:1e3,maxStack:100,userOnly:!1}...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.on(r.Ay.events.EDITOR_CHANGE,((...
    method change (line 2) | change(t,e){if(0===this.stack[t].length)return;const n=this.stack[t].p...
    method clear (line 2) | clear(){this.stack={undo:[],redo:[]}}
    method cutoff (line 2) | cutoff(){this.lastRecorded=0}
    method record (line 2) | record(t,e){if(0===t.ops.length)return;this.stack.redo=[];let n=t.inve...
    method redo (line 2) | redo(){this.change("redo","undo")}
    method transform (line 2) | transform(t){E(this.stack.undo,t),E(this.stack.redo,t)}
    method undo (line 2) | undo(){this.change("undo","redo")}
    method restoreSelection (line 2) | restoreSelection(t){if(t.range)this.quill.setSelection(t.range,r.Ay.so...
    method create (line 2) | static create(){return super.create()}
    method formats (line 2) | static formats(){return!0}
    method optimize (line 2) | optimize(t){super.optimize(t),this.domNode.tagName!==this.statics.tagN...
  function E (line 2) | function E(t,e){let n=e;for(let e=t.length-1;e>=0;e-=1){const r=t[e];t[e...
  function w (line 2) | function w(t,e){if(!t)return t;const n=e.transformPosition(t.index);retu...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("href",...
    method formats (line 2) | static formats(t){return t.getAttribute("href")}
    method sanitize (line 2) | static sanitize(t){return q(t,this.PROTOCOL_WHITELIST)?t:this.SANITIZE...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("hr...
  class k (line 2) | class k extends x.A{constructor(t,e){super(t,e),t.root.addEventListener(...
    method constructor (line 2) | constructor(t,e){super(t,e),t.root.addEventListener("drop",(e=>{e.prev...
    method upload (line 2) | upload(t,e){const n=[];Array.from(e).forEach((t=>{t&&this.options.mime...
    method create (line 2) | static create(t){return"super"===t?document.createElement("sup"):"sub"...
    method formats (line 2) | static formats(t){return"SUB"===t.tagName?"sub":"SUP"===t.tagName?"sup...
  method handler (line 2) | handler(t,e){if(!this.quill.scroll.query("image"))return;const n=e.map((...
  class S (line 2) | class S extends x.A{constructor(t,e){super(t,e),t.root.addEventListener(...
    method constructor (line 2) | constructor(t,e){super(t,e),t.root.addEventListener("beforeinput",(t=>...
    method deleteRange (line 2) | deleteRange(t){(0,q.Xo)({range:t,quill:this.quill})}
    method replaceText (line 2) | replaceText(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method handleBeforeInput (line 2) | handleBeforeInput(t){if(this.quill.composition.isComposing||t.defaultP...
    method handleCompositionStart (line 2) | handleCompositionStart(){const t=this.quill.getSelection();t&&this.rep...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.root.addEventListener("copy",(t...
    method addMatcher (line 2) | addMatcher(t,e){this.matchers.push([t,e])}
    method convert (line 2) | convert(t){let{html:e,text:n}=t,r=arguments.length>1&&void 0!==argumen...
    method normalizeHTML (line 2) | normalizeHTML(t){(t=>{t.documentElement&&w.forEach((e=>{e(t)}))})(t)}
    method convertHTML (line 2) | convertHTML(t){const e=(new DOMParser).parseFromString(t,"text/html");...
    method dangerouslyPasteHTML (line 2) | dangerouslyPasteHTML(t,e){let n=arguments.length>2&&void 0!==arguments...
    method onCaptureCopy (line 2) | onCaptureCopy(t){let e=arguments.length>1&&void 0!==arguments[1]&&argu...
    method normalizeURIList (line 2) | normalizeURIList(t){return t.split(/\r?\n/).filter((t=>"#"!==t[0])).jo...
    method onCapturePaste (line 2) | onCapturePaste(t){if(t.defaultPrevented||!this.quill.isEnabled())retur...
    method onCopy (line 2) | onCopy(t){const e=this.quill.getText(t);return{html:this.quill.getSema...
    method onPaste (line 2) | onPaste(t,e){let{text:n,html:r}=e;const i=this.quill.getFormat(t.index...
    method prepareMatching (line 2) | prepareMatching(t,e){const n=[],r=[];return this.matchers.forEach((i=>...
  class j (line 2) | class j extends x.A{isListening=!1;selectionChangeDeadline=0;constructor...
    method constructor (line 2) | constructor(t,e){super(t,e),this.handleArrowKeys(),this.handleNavigati...
    method handleArrowKeys (line 2) | handleArrowKeys(){this.quill.keyboard.addBinding({key:["ArrowLeft","Ar...
    method handleNavigationShortcuts (line 2) | handleNavigationShortcuts(){this.quill.root.addEventListener("keydown"...
    method ensureListeningToSelectionChange (line 2) | ensureListeningToSelectionChange(){this.selectionChangeDeadline=Date.n...
    method handleSelectionChange (line 2) | handleSelectionChange(){const t=document.getSelection();if(!t)return;c...
  method constructor (line 2) | constructor(){super(),this.domListeners={},this.on("error",s.error)}
  method emit (line 2) | emit(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=argume...
  method handleDOM (line 2) | handleDOM(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r<e;r...
  method listenDOM (line 2) | listenDOM(t,e,n){this.domListeners[t]||(this.domListeners[t]=[]),this.do...
  function i (line 2) | function i(t){if(r&&n.indexOf(t)<=n.indexOf(r)){for(var e=arguments.leng...
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  function s (line 2) | function s(t){return n.reduce(((e,n)=>(e[n]=i.bind(console,n,t),e)),{})}
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments...
  function g (line 2) | function g(t,e,n){if(0===t.length){const[t]=y(n.pop());return e<=0?`</li...
  function m (line 2) | function m(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]&&argum...
    method constructor (line 2) | constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.bat...
    method batchStart (line 2) | batchStart(){Array.isArray(this.batch)||(this.batch=[])}
    method batchEnd (line 2) | batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this...
    method emitMount (line 2) | emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}
    method emitUnmount (line 2) | emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}
    method emitEmbedUpdate (line 2) | emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,...
    method deleteAt (line 2) | deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.dele...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}
    method insertAt (line 2) | insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.quer...
    method insertBefore (line 2) | insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=th...
    method insertContents (line 2) | insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d()...
    method isEnabled (line 2) | isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}
    method leaf (line 2) | leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;...
    method line (line 2) | line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}
    method lines (line 2) | lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0...
    method optimize (line 2) | optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method path (line 2) | path(t){return super.path(t).slice(1)}
    method remove (line 2) | remove(){}
    method update (line 2) | update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this...
    method updateEmbedAt (line 2) | updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t...
    method handleDragStart (line 2) | handleDragStart(t){t.preventDefault()}
    method deltaToRenderBlocks (line 2) | deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>...
    method createBlock (line 2) | createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e...
    method create (line 2) | static create(t){const e=super.create();return e.setAttribute("data-li...
    method formats (line 2) | static formats(t){return t.getAttribute("data-list")||void 0}
    method register (line 2) | static register(){p.Ay.register(g)}
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("spa...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
  function b (line 2) | function b(t,e){return Object.keys(e).reduce(((n,r)=>{if(null==t[r])retu...
    method constructor (line 2) | constructor(){this.head=null,this.tail=null,this.length=0}
    method append (line 2) | append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.sli...
    method at (line 2) | at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}
    method contains (line 2) | contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return...
    method indexOf (line 2) | indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)ret...
    method insertBefore (line 2) | insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e....
    method offset (line 2) | offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.le...
    method remove (line 2) | remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=...
    method iterator (line 2) | iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}
    method find (line 2) | find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.leng...
    method forEach (line 2) | forEach(t){const e=this.iterator();let n=e();for(;n;)t(n),n=e()}
    method forEachAt (line 2) | forEachAt(t,e,n){if(e<=0)return;const[r,i]=this.find(t);let s=t-i;cons...
    method map (line 2) | map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}
    method reduce (line 2) | reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();r...
  function y (line 2) | function y(t){const e="ordered"===t?"ol":"ul";switch(t){case"checked":re...
  function v (line 2) | function v(t){return t.reduce(((t,e)=>{if("string"==typeof e.insert){con...
  function A (line 2) | function A(t,e){let{index:n,length:r}=t;return new f.Q(n+e,r)}
  method constructor (line 2) | constructor(t){this.scroll=t,this.delta=this.getDelta()}
  method applyDelta (line 2) | applyDelta(t){this.scroll.update();let e=this.scroll.length();this.scrol...
  method deleteText (line 2) | deleteText(t,e){return this.scroll.deleteAt(t,e),this.update((new(o()))....
  method formatLine (line 2) | formatLine(t,e){let n=arguments.length>2&&void 0!==arguments[2]?argument...
  method formatText (line 2) | formatText(t,e){let n=arguments.length>2&&void 0!==arguments[2]?argument...
  method getContents (line 2) | getContents(t,e){return this.delta.slice(t,t+e)}
  method getDelta (line 2) | getDelta(){return this.scroll.lines().reduce(((t,e)=>t.concat(e.delta())...
  method getFormat (line 2) | getFormat(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1...
  method getHTML (line 2) | getHTML(t,e){const[n,r]=this.scroll.line(t);if(n){const i=n.length();ret...
  method getText (line 2) | getText(t,e){return this.getContents(t,e).filter((t=>"string"==typeof t....
  method insertContents (line 2) | insertContents(t,e){const n=v(e),r=(new(o())).retain(t).concat(n);return...
  method insertEmbed (line 2) | insertEmbed(t,e,n){return this.scroll.insertAt(t,e,n),this.update((new(o...
  method insertText (line 2) | insertText(t,e){let n=arguments.length>2&&void 0!==arguments[2]?argument...
  method isBlank (line 2) | isBlank(){if(0===this.scroll.children.length)return!0;if(this.scroll.chi...
  method removeFormat (line 2) | removeFormat(t,e){const n=this.getText(t,e),[r,i]=this.scroll.line(t+e);...
  method update (line 2) | update(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[...
  method constructor (line 2) | constructor(t,e){this.scroll=t,this.emitter=e,this.setupListeners()}
  method setupListeners (line 2) | setupListeners(){this.scroll.domNode.addEventListener("compositionstart"...
  method handleCompositionStart (line 2) | handleCompositionStart(t){const e=t.target instanceof Node?this.scroll.f...
  method handleCompositionEnd (line 2) | handleCompositionEnd(t){this.emitter.emit(N.A.events.COMPOSITION_BEFORE_...
  class I (line 2) | class I{static DEFAULTS={bounds:null,modules:{clipboard:!0,keyboard:!0,h...
    method debug (line 2) | static debug(t){!0===t&&(t="log"),w.A.level(t)}
    method find (line 2) | static find(t){let e=arguments.length>1&&void 0!==arguments[1]&&argume...
    method import (line 2) | static import(t){return null==this.imports[t]&&C.error(`Cannot import ...
    method register (line 2) | static register(){if("string"!=typeof(arguments.length<=0?void 0:argum...
    method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method addContainer (line 2) | addContainer(t){let e=arguments.length>1&&void 0!==arguments[1]?argume...
    method blur (line 2) | blur(){this.selection.setRange(null)}
    method deleteText (line 2) | deleteText(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.editor...
    method disable (line 2) | disable(){this.enable(!1)}
    method editReadOnly (line 2) | editReadOnly(t){this.allowReadOnlyEdits=!0;const e=t();return this.all...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method focus (line 2) | focus(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{...
    method format (line 2) | format(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[...
    method formatLine (line 2) | formatLine(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(...
    method formatText (line 2) | formatText(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(...
    method getBounds (line 2) | getBounds(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments...
    method getContents (line 2) | getContents(){let t=arguments.length>0&&void 0!==arguments[0]?argument...
    method getFormat (line 2) | getFormat(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[...
    method getIndex (line 2) | getIndex(t){return t.offset(this.scroll)}
    method getLength (line 2) | getLength(){return this.scroll.length()}
    method getLeaf (line 2) | getLeaf(t){return this.scroll.leaf(t)}
    method getLine (line 2) | getLine(t){return this.scroll.line(t)}
    method getLines (line 2) | getLines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method getModule (line 2) | getModule(t){return this.theme.modules[t]}
    method getSelection (line 2) | getSelection(){return arguments.length>0&&void 0!==arguments[0]&&argum...
    method getSemanticHTML (line 2) | getSemanticHTML(){let t=arguments.length>0&&void 0!==arguments[0]?argu...
    method getText (line 2) | getText(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]...
    method hasFocus (line 2) | hasFocus(){return this.selection.hasFocus()}
    method insertEmbed (line 2) | insertEmbed(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]?arg...
    method insertText (line 2) | insertText(t,e,n,r,i){let s;return[t,,s,i]=P(t,0,n,r,i),D.call(this,((...
    method isEnabled (line 2) | isEnabled(){return this.scroll.isEnabled()}
    method off (line 2) | off(){return this.emitter.off(...arguments)}
    method on (line 2) | on(){return this.emitter.on(...arguments)}
    method once (line 2) | once(){return this.emitter.once(...arguments)}
    method removeFormat (line 2) | removeFormat(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.edit...
    method scrollRectIntoView (line 2) | scrollRectIntoView(t){((t,e)=>{const n=t.ownerDocument;let r=e,i=t;for...
    method scrollIntoView (line 2) | scrollIntoView(){console.warn("Quill#scrollIntoView() has been depreca...
    method scrollSelectionIntoView (line 2) | scrollSelectionIntoView(){const t=this.selection.lastRange,e=t&&this.s...
    method setContents (line 2) | setContents(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method setSelection (line 2) | setSelection(t,e,n){null==t?this.selection.setRange(null,e||I.sources....
    method setText (line 2) | setText(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1...
    method update (line 2) | update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:...
    method updateContents (line 2) | updateContents(t){let e=arguments.length>1&&void 0!==arguments[1]?argu...
  function B (line 2) | function B(t){return"string"==typeof t?document.querySelector(t):t}
  function M (line 2) | function M(t){return Object.entries(t??{}).reduce(((t,e)=>{let[n,r]=e;re...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("frameb...
    method formats (line 2) | static formats(t){return B.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t....
    method sanitize (line 2) | static sanitize(t){return w.sanitize(t)}
    method value (line 2) | static value(t){return t.getAttribute("src")}
    method format (line 2) | format(t,e){B.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domN...
    method html (line 2) | html(){const{video:t}=this.value();return`<a href="${t}">${t}</a>`}
  function U (line 2) | function U(t){return Object.fromEntries(Object.entries(t).filter((t=>voi...
  function D (line 2) | function D(t,e,n,r){if(!this.isEnabled()&&e===N.A.sources.USER&&!this.al...
  function P (line 2) | function P(t,e,n,r,i){let s={};return"number"==typeof t.index&&"number"=...
  function z (line 2) | function z(t,e,n,r){const i="number"==typeof n?n:0;if(null==t)return nul...
  class a (line 2) | class a{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?a...
    method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
  function c (line 2) | function c(t,e){try{e.parentNode}catch(t){return!1}return t.contains(e)}
    method delta (line 2) | delta(){return null==this.cache.delta&&(this.cache.delta=h(this)),this...
    method deleteAt (line 2) | deleteAt(t,e){super.deleteAt(t,e),this.cache={}}
    method formatAt (line 2) | formatAt(t,e,n,i){e<=0||(this.scroll.query(n,r.Scope.BLOCK)?t+e===this...
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return super.insertAt(t,e,n),void(this.cach...
    method insertBefore (line 2) | insertBefore(t,e){const{head:n}=this.children;super.insertBefore(t,e),...
    method length (line 2) | length(){return null==this.cache.length&&(this.cache.length=super.leng...
    method moveChildren (line 2) | moveChildren(t,e){super.moveChildren(t,e),this.cache={}}
    method optimize (line 2) | optimize(t){super.optimize(t),this.cache={}}
    method path (line 2) | path(t){return super.path(t,!0)}
    method removeChild (line 2) | removeChild(t){super.removeChild(t),this.cache={}}
    method split (line 2) | split(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1]...
  method constructor (line 2) | constructor(t,e){this.emitter=e,this.scroll=t,this.composing=!1,this.mou...
  method handleComposition (line 2) | handleComposition(){this.emitter.on(o.A.events.COMPOSITION_BEFORE_START,...
  method handleDragging (line 2) | handleDragging(){this.emitter.listenDOM("mousedown",document.body,(()=>{...
  method focus (line 2) | focus(){this.hasFocus()||(this.root.focus({preventScroll:!0}),this.setRa...
  method format (line 2) | format(t,e){this.scroll.update();const n=this.getNativeRange();if(null!=...
  method getBounds (line 2) | getBounds(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1...
  method getNativeRange (line 2) | getNativeRange(){const t=document.getSelection();if(null==t||t.rangeCoun...
  method getRange (line 2) | getRange(){const t=this.scroll.domNode;if("isConnected"in t&&!t.isConnec...
  method hasFocus (line 2) | hasFocus(){return document.activeElement===this.root||null!=document.act...
  method normalizedToRange (line 2) | normalizedToRange(t){const e=[[t.start.node,t.start.offset]];t.native.co...
  method normalizeNative (line 2) | normalizeNative(t){if(!c(this.root,t.startContainer)||!t.collapsed&&!c(t...
  method rangeToNative (line 2) | rangeToNative(t){const e=this.scroll.length(),n=(t,n)=>{t=Math.min(e-1,t...
  method setNativeRange (line 2) | setNativeRange(t,e){let n=arguments.length>2&&void 0!==arguments[2]?argu...
  method setRange (line 2) | setRange(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1...
  method update (line 2) | update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o....
  class n (line 2) | class n{static DEFAULTS={modules:{}};static themes={default:n};modules={...
    method constructor (line 2) | constructor(t,e){this.quill=t,this.options=e}
    method init (line 2) | init(){Object.keys(this.options.modules).forEach((t=>{null==this.modul...
    method addModule (line 2) | addModule(t){const e=this.quill.constructor.import(`modules/${t}`);ret...
  class u (line 2) | class u extends a.A{static create(t){const e=super.create(t);return e.se...
    method attach (line 2) | attach(){super.attach(),this.attributes=new r.AttributorStore(this.dom...
    method delta (line 2) | delta(){return(new(s())).insert(this.value(),{...this.formats(),...thi...
    method format (line 2) | format(t,e){const n=this.scroll.query(t,r.Scope.BLOCK_ATTRIBUTE);null!...
    method formatAt (line 2) | formatAt(t,e,n,r){this.format(n,r)}
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return void super.insertAt(t,e,n);const r=e...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("spellc...
    method code (line 2) | code(t,e){return this.children.map((t=>t.length()<=1?"":t.domNode.inne...
    method html (line 2) | html(t,e){return`<pre>\n${(0,l.X)(this.code(t,e))}\n</pre>`}
  class h (line 2) | class h extends r.Ay{static TAB="  ";static register(){c.Ay.register(u)}}
    method register (line 2) | static register(){c.Ay.register(u)}
    method constructor (line 2) | constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.op...
    method registerEmbed (line 2) | static registerEmbed(t,e){this.handlers[t]=e}
    method unregisterEmbed (line 2) | static unregisterEmbed(t){delete this.handlers[t]}
    method getHandler (line 2) | static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`n...
    method insert (line 2) | insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n....
    method delete (line 2) | delete(t){return t<=0?this:this.push({delete:t})}
    method retain (line 2) | retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t}...
    method push (line 2) | push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==type...
    method chop (line 2) | chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof ...
    method filter (line 2) | filter(t){return this.ops.filter(t)}
    method forEach (line 2) | forEach(t){this.ops.forEach(t)}
    method map (line 2) | map(t){return this.ops.map(t)}
    method partition (line 2) | partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(...
    method reduce (line 2) | reduce(t,e){return this.ops.reduce(t,e)}
    method changeLength (line 2) | changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(...
    method length (line 2) | length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}
    method slice (line 2) | slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i<e...
    method compose (line 2) | compose(t){const e=new a.default(this.ops),n=new a.default(t.ops),r=[]...
    method concat (line 2) | concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.pu...
    method diff (line 2) | diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e....
    method eachLine (line 2) | eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for...
    method invert (line 2) | invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.dele...
    method transform (line 2) | transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPos...
    method transformPosition (line 2) | transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=...
    method formats (line 2) | static formats(t){return this.tagName.indexOf(t.tagName)+1}
  class d (line 2) | class d extends o.A{}
  class i (line 2) | class i extends r.StyleAttributor{value(t){let e=super.value(t);return e...
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  class o (line 2) | class o extends r.StyleAttributor{value(t){return super.value(t).replace...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  class S (line 2) | class S extends a.A{static DEFAULTS={matchers:[]};constructor(t,e){super...
    method constructor (line 2) | constructor(t,e){super(t,e),t.root.addEventListener("beforeinput",(t=>...
    method deleteRange (line 2) | deleteRange(t){(0,q.Xo)({range:t,quill:this.quill})}
    method replaceText (line 2) | replaceText(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method handleBeforeInput (line 2) | handleBeforeInput(t){if(this.quill.composition.isComposing||t.defaultP...
    method handleCompositionStart (line 2) | handleCompositionStart(){const t=this.quill.getSelection();t&&this.rep...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.root.addEventListener("copy",(t...
    method addMatcher (line 2) | addMatcher(t,e){this.matchers.push([t,e])}
    method convert (line 2) | convert(t){let{html:e,text:n}=t,r=arguments.length>1&&void 0!==argumen...
    method normalizeHTML (line 2) | normalizeHTML(t){(t=>{t.documentElement&&w.forEach((e=>{e(t)}))})(t)}
    method convertHTML (line 2) | convertHTML(t){const e=(new DOMParser).parseFromString(t,"text/html");...
    method dangerouslyPasteHTML (line 2) | dangerouslyPasteHTML(t,e){let n=arguments.length>2&&void 0!==arguments...
    method onCaptureCopy (line 2) | onCaptureCopy(t){let e=arguments.length>1&&void 0!==arguments[1]&&argu...
    method normalizeURIList (line 2) | normalizeURIList(t){return t.split(/\r?\n/).filter((t=>"#"!==t[0])).jo...
    method onCapturePaste (line 2) | onCapturePaste(t){if(t.defaultPrevented||!this.quill.isEnabled())retur...
    method onCopy (line 2) | onCopy(t){const e=this.quill.getText(t);return{html:this.quill.getSema...
    method onPaste (line 2) | onPaste(t,e){let{text:n,html:r}=e;const i=this.quill.getFormat(t.index...
    method prepareMatching (line 2) | prepareMatching(t,e){const n=[],r=[];return this.matchers.forEach((i=>...
  function O (line 2) | function O(t,e,n,r){return r.query(e)?t.reduce(((t,r)=>{if(!r.insert)ret...
  function T (line 2) | function T(t,e){let n="";for(let r=t.ops.length-1;r>=0&&n.length<e.lengt...
    method create (line 2) | static create(t){if(null==window.katex)throw new Error("Formula module...
    method value (line 2) | static value(t){return t.getAttribute("data-value")}
    method html (line 2) | html(){const{formula:t}=this.value();return`<span>${t}</span>`}
  function j (line 2) | function j(t,e){if(!(t instanceof Element))return!1;const n=e.query(t);r...
    method constructor (line 2) | constructor(t,e){super(t,e),this.handleArrowKeys(),this.handleNavigati...
    method handleArrowKeys (line 2) | handleArrowKeys(){this.quill.keyboard.addBinding({key:["ArrowLeft","Ar...
    method handleNavigationShortcuts (line 2) | handleNavigationShortcuts(){this.quill.root.addEventListener("keydown"...
    method ensureListeningToSelectionChange (line 2) | ensureListeningToSelectionChange(){this.selectionChangeDeadline=Date.n...
    method handleSelectionChange (line 2) | handleSelectionChange(){const t=document.getSelection();if(!t)return;c...
  function R (line 2) | function R(t){return null!=t&&(C.has(t)||("PRE"===t.tagName?C.set(t,!0):...
    method create (line 2) | static create(t){const e=super.create(t);return"string"==typeof t&&e.s...
    method formats (line 2) | static formats(t){return C.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t....
    method match (line 2) | static match(t){return/\.(jpe?g|gif|png)$/.test(t)||/^data:image\/.+;b...
    method sanitize (line 2) | static sanitize(t){return q(t,["http","https","data"])?t:"//:0"}
    method value (line 2) | static value(t){return t.getAttribute("src")}
    method format (line 2) | format(t,e){C.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domN...
  function I (line 2) | function I(t,e,n,r,i){return e.nodeType===e.TEXT_NODE?r.reduce(((n,r)=>r...
    method debug (line 2) | static debug(t){!0===t&&(t="log"),w.A.level(t)}
    method find (line 2) | static find(t){let e=arguments.length>1&&void 0!==arguments[1]&&argume...
    method import (line 2) | static import(t){return null==this.imports[t]&&C.error(`Cannot import ...
    method register (line 2) | static register(){if("string"!=typeof(arguments.length<=0?void 0:argum...
    method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method addContainer (line 2) | addContainer(t){let e=arguments.length>1&&void 0!==arguments[1]?argume...
    method blur (line 2) | blur(){this.selection.setRange(null)}
    method deleteText (line 2) | deleteText(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.editor...
    method disable (line 2) | disable(){this.enable(!1)}
    method editReadOnly (line 2) | editReadOnly(t){this.allowReadOnlyEdits=!0;const e=t();return this.all...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method focus (line 2) | focus(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{...
    method format (line 2) | format(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[...
    method formatLine (line 2) | formatLine(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(...
    method formatText (line 2) | formatText(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(...
    method getBounds (line 2) | getBounds(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments...
    method getContents (line 2) | getContents(){let t=arguments.length>0&&void 0!==arguments[0]?argument...
    method getFormat (line 2) | getFormat(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[...
    method getIndex (line 2) | getIndex(t){return t.offset(this.scroll)}
    method getLength (line 2) | getLength(){return this.scroll.length()}
    method getLeaf (line 2) | getLeaf(t){return this.scroll.leaf(t)}
    method getLine (line 2) | getLine(t){return this.scroll.line(t)}
    method getLines (line 2) | getLines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method getModule (line 2) | getModule(t){return this.theme.modules[t]}
    method getSelection (line 2) | getSelection(){return arguments.length>0&&void 0!==arguments[0]&&argum...
    method getSemanticHTML (line 2) | getSemanticHTML(){let t=arguments.length>0&&void 0!==arguments[0]?argu...
    method getText (line 2) | getText(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]...
    method hasFocus (line 2) | hasFocus(){return this.selection.hasFocus()}
    method insertEmbed (line 2) | insertEmbed(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]?arg...
    method insertText (line 2) | insertText(t,e,n,r,i){let s;return[t,,s,i]=P(t,0,n,r,i),D.call(this,((...
    method isEnabled (line 2) | isEnabled(){return this.scroll.isEnabled()}
    method off (line 2) | off(){return this.emitter.off(...arguments)}
    method on (line 2) | on(){return this.emitter.on(...arguments)}
    method once (line 2) | once(){return this.emitter.once(...arguments)}
    method removeFormat (line 2) | removeFormat(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.edit...
    method scrollRectIntoView (line 2) | scrollRectIntoView(t){((t,e)=>{const n=t.ownerDocument;let r=e,i=t;for...
    method scrollIntoView (line 2) | scrollIntoView(){console.warn("Quill#scrollIntoView() has been depreca...
    method scrollSelectionIntoView (line 2) | scrollSelectionIntoView(){const t=this.selection.lastRange,e=t&&this.s...
    method setContents (line 2) | setContents(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
    method setSelection (line 2) | setSelection(t,e,n){null==t?this.selection.setRange(null,e||I.sources....
    method setText (line 2) | setText(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1...
    method update (line 2) | update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:...
    method updateContents (line 2) | updateContents(t){let e=arguments.length>1&&void 0!==arguments[1]?argu...
  function B (line 2) | function B(t){return(e,n,r)=>O(n,t,!0,r)}
  function M (line 2) | function M(t,e,n){if(!T(e,"\n")){if(j(t,n)&&(t.childNodes.length>0||t in...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("frameb...
    method formats (line 2) | static formats(t){return B.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t....
    method sanitize (line 2) | static sanitize(t){return w.sanitize(t)}
    method value (line 2) | static value(t){return t.getAttribute("src")}
    method format (line 2) | format(t,e){B.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domN...
    method html (line 2) | html(){const{video:t}=this.value();return`<a href="${t}">${t}</a>`}
  class f (line 2) | class f extends u.A{static match(t,e){return!["altKey","ctrlKey","metaKe...
    method match (line 2) | static match(t,e){return!["altKey","ctrlKey","metaKey","shiftKey"].som...
    method constructor (line 2) | constructor(t,e){super(t,e),this.bindings={},Object.keys(this.options....
    method addBinding (line 2) | addBinding(t){let e=arguments.length>1&&void 0!==arguments[1]?argument...
    method listen (line 2) | listen(){this.quill.root.addEventListener("keydown",(t=>{if(t.defaultP...
    method handleBackspace (line 2) | handleBackspace(t,e){const n=/[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(e....
    method handleDelete (line 2) | handleDelete(t,e){const n=/^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(e.suf...
    method handleDeleteRange (line 2) | handleDeleteRange(t){v({range:t,quill:this.quill}),this.quill.focus()}
    method handleEnter (line 2) | handleEnter(t,e){const n=Object.keys(e.format).reduce(((t,n)=>(this.qu...
  method handler (line 2) | handler(t,e){return!(!e.collapsed||0===e.offset)||(this.quill.format("in...
  method handler (line 2) | handler(t,e){return!(!e.collapsed||0===e.offset)||(this.quill.format("in...
  method handler (line 2) | handler(t,e){null!=e.format.indent?this.quill.format("indent","-1",a.Ay....
  method handler (line 2) | handler(t){this.quill.deleteText(t.index-1,1,a.Ay.sources.USER)}
  method handler (line 2) | handler(t,e){if(e.format.table)return!0;this.quill.history.cutoff();cons...
  method handler (line 2) | handler(){this.quill.format("blockquote",!1,a.Ay.sources.USER)}
  method handler (line 2) | handler(t,e){const n={list:!1};e.format.indent&&(n.indent=!1),this.quill...
  method handler (line 2) | handler(t){const[e,n]=this.quill.getLine(t.index),r={...e.formats(),list...
  method handler (line 2) | handler(t,e){const[n,r]=this.quill.getLine(t.index),i=(new(o())).retain(...
  method handler (line 2) | handler(){}
  method handler (line 2) | handler(){}
  method handler (line 2) | handler(t){const e=this.quill.getModule("table");if(e){const[n,r,i,s]=e....
  method handler (line 2) | handler(t,e){const{event:n,line:r}=e,i=r.offset(this.quill.scroll);n.shi...
  method handler (line 2) | handler(t,e){if(null==this.quill.scroll.query("list"))return!0;const{len...
  method handler (line 2) | handler(t){const[e,n]=this.quill.getLine(t.index);let r=2,i=e;for(;null!...
  function g (line 2) | function g(t){return{key:"Tab",shiftKey:!t,format:{"code-block":!0},hand...
  function m (line 2) | function m(t,e){return{key:t,shiftKey:e,altKey:null,["ArrowLeft"===t?"pr...
    method constructor (line 2) | constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.bat...
    method batchStart (line 2) | batchStart(){Array.isArray(this.batch)||(this.batch=[])}
    method batchEnd (line 2) | batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this...
    method emitMount (line 2) | emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}
    method emitUnmount (line 2) | emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}
    method emitEmbedUpdate (line 2) | emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,...
    method deleteAt (line 2) | deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.dele...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}
    method insertAt (line 2) | insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.quer...
    method insertBefore (line 2) | insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=th...
    method insertContents (line 2) | insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d()...
    method isEnabled (line 2) | isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}
    method leaf (line 2) | leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;...
    method line (line 2) | line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}
    method lines (line 2) | lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0...
    method optimize (line 2) | optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method path (line 2) | path(t){return super.path(t).slice(1)}
    method remove (line 2) | remove(){}
    method update (line 2) | update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this...
    method updateEmbedAt (line 2) | updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t...
    method handleDragStart (line 2) | handleDragStart(t){t.preventDefault()}
    method deltaToRenderBlocks (line 2) | deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>...
    method createBlock (line 2) | createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e...
    method create (line 2) | static create(t){const e=super.create();return e.setAttribute("data-li...
    method formats (line 2) | static formats(t){return t.getAttribute("data-list")||void 0}
    method register (line 2) | static register(){p.Ay.register(g)}
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("spa...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
  function b (line 2) | function b(t){return{key:t[0],shortKey:!0,handler(e,n){this.quill.format...
    method constructor (line 2) | constructor(){this.head=null,this.tail=null,this.length=0}
    method append (line 2) | append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.sli...
    method at (line 2) | at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}
    method contains (line 2) | contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return...
    method indexOf (line 2) | indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)ret...
    method insertBefore (line 2) | insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e....
    method offset (line 2) | offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.le...
    method remove (line 2) | remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=...
    method iterator (line 2) | iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}
    method find (line 2) | find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.leng...
    method forEach (line 2) | forEach(t){const e=this.iterator();let n=e();for(;n;)t(n),n=e()}
    method forEachAt (line 2) | forEachAt(t,e,n){if(e<=0)return;const[r,i]=this.find(t);let s=t-i;cons...
    method map (line 2) | map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}
    method reduce (line 2) | reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();r...
  function y (line 2) | function y(t){return{key:t?"ArrowUp":"ArrowDown",collapsed:!0,format:["t...
  function v (line 2) | function v(t){let{quill:e,range:n}=t;const r=e.getLines(n);let i={};if(r...
  function r (line 2) | function r(){}
  function i (line 2) | function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  function s (line 2) | function s(t,e,r,s,o){if("function"!=typeof r)throw new TypeError("The l...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  function o (line 2) | function o(t,e){0==--t._eventsCount?t._events=new r:delete t._events[e]}
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  function l (line 2) | function l(){this._events=new r,this._eventsCount=0}
  function i (line 2) | function i(t,g,m,b,y){if(t===g)return t?[[r,t]]:[];if(null!=m){var A=fun...
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  function s (line 2) | function s(t,e,n,r){var s=t.substring(0,n),o=e.substring(0,r),l=t.substr...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  function o (line 2) | function o(t,e){if(!t||!e||t.charAt(0)!==e.charAt(0))return 0;for(var n=...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  function l (line 2) | function l(t,e){var n=t.length,r=e.length;if(0==n||0==r)return 0;n>r?t=t...
  function a (line 2) | function a(t,e){if(!t||!e||t.slice(-1)!==e.slice(-1))return 0;for(var n=...
    method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
  function p (line 2) | function p(t,i){t.push([r,""]);for(var s,l=0,c=0,u=0,h="",d="";l<t.lengt...
  function g (line 2) | function g(t){return t>=55296&&t<=56319}
  function m (line 2) | function m(t){return t>=56320&&t<=57343}
    method constructor (line 2) | constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.bat...
    method batchStart (line 2) | batchStart(){Array.isArray(this.batch)||(this.batch=[])}
    method batchEnd (line 2) | batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this...
    method emitMount (line 2) | emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}
    method emitUnmount (line 2) | emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}
    method emitEmbedUpdate (line 2) | emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,...
    method deleteAt (line 2) | deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.dele...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}
    method insertAt (line 2) | insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.quer...
    method insertBefore (line 2) | insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=th...
    method insertContents (line 2) | insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d()...
    method isEnabled (line 2) | isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}
    method leaf (line 2) | leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;...
    method line (line 2) | line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}
    method lines (line 2) | lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0...
    method optimize (line 2) | optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method path (line 2) | path(t){return super.path(t).slice(1)}
    method remove (line 2) | remove(){}
    method update (line 2) | update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this...
    method updateEmbedAt (line 2) | updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t...
    method handleDragStart (line 2) | handleDragStart(t){t.preventDefault()}
    method deltaToRenderBlocks (line 2) | deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>...
    method createBlock (line 2) | createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e...
    method create (line 2) | static create(t){const e=super.create();return e.setAttribute("data-li...
    method formats (line 2) | static formats(t){return t.getAttribute("data-list")||void 0}
    method register (line 2) | static register(){p.Ay.register(g)}
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("spa...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
  function b (line 2) | function b(t){return m(t.charCodeAt(0))}
    method constructor (line 2) | constructor(){this.head=null,this.tail=null,this.length=0}
    method append (line 2) | append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.sli...
    method at (line 2) | at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}
    method contains (line 2) | contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return...
    method indexOf (line 2) | indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)ret...
    method insertBefore (line 2) | insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e....
    method offset (line 2) | offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.le...
    method remove (line 2) | remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=...
    method iterator (line 2) | iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}
    method find (line 2) | find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.leng...
    method forEach (line 2) | forEach(t){const e=this.iterator();let n=e();for(;n;)t(n),n=e()}
    method forEachAt (line 2) | forEachAt(t,e,n){if(e<=0)return;const[r,i]=this.find(t);let s=t-i;cons...
    method map (line 2) | map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}
    method reduce (line 2) | reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();r...
  function y (line 2) | function y(t){return g(t.charCodeAt(t.length-1))}
  function v (line 2) | function v(t,i,s,o){return y(t)||b(o)?null:function(t){for(var e=[],n=0;...
  function A (line 2) | function A(t,e,n,r){return i(t,e,n,r,!0)}
  function P (line 2) | function P(t,e){return t.set(e[0],e[1]),t}
  function z (line 2) | function z(t,e){return t.add(e),t}
  function F (line 2) | function F(t,e,n,r){var i=-1,s=t?t.length:0;for(r&&s&&(n=t[++i]);++i<s;)...
  function H (line 2) | function H(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!...
  function $ (line 2) | function $(t){var e=-1,n=Array(t.size);return t.forEach((function(t,r){n...
  function V (line 2) | function V(t,e){return function(n){return t(e(n))}}
  function K (line 2) | function K(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[+...
  function kt (line 2) | function kt(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[...
  function _t (line 2) | function _t(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[...
  function Lt (line 2) | function Lt(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var r=t[...
  function St (line 2) | function St(t){this.__data__=new _t(t)}
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.on(bt.A.events.EDITOR_CHANGE,((...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector(".ql-close").addEventL...
    method cancel (line 2) | cancel(){this.show()}
    method position (line 2) | position(t){const e=super.position(t),n=this.root.querySelector(".ql-t...
  function Ot (line 2) | function Ot(t,e,n){var r=t[e];tt.call(t,e)&&Ft(r,n)&&(void 0!==n||e in t...
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){this.tooltip=new St(this.quill,this.options.bounds),n...
  function Tt (line 2) | function Tt(t,e){for(var n=t.length;n--;)if(Ft(t[n][0],e))return n;retur...
  function jt (line 2) | function jt(t,e,n,r,i,f,y){var T;if(r&&(T=f?r(t,i,f,y):r(t)),void 0!==T)...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector("a.ql-action").addEven...
    method show (line 2) | show(){super.show(),this.root.removeAttribute("data-mode")}
  function Ct (line 2) | function Ct(t){var e=new t.constructor(t.byteLength);return new st(e).se...
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){null!=t.container&&(t.container.classList.add("ql-sno...
  function Rt (line 2) | function Rt(t,e,n,r){n||(n={});for(var i=-1,s=e.length;++i<s;){var o=e[i...
  function It (line 2) | function It(t,e){var n,r,i=t.__data__;return("string"==(r=typeof(n=e))||...
  function Bt (line 2) | function Bt(t,e){var n=function(t,e){return null==t?void 0:t[e]}(t,e);re...
  function Dt (line 2) | function Dt(t,e){return!!(e=null==e?i:e)&&("number"==typeof t||j.test(t)...
  function Pt (line 2) | function Pt(t){var e=t&&t.constructor;return t===("function"==typeof e&&...
  function zt (line 2) | function zt(t){if(null!=t){try{return Y.call(t)}catch(t){}try{return t+"...
  function Ft (line 2) | function Ft(t,e){return t===e||t!=t&&e!=e}
  function $t (line 2) | function $t(t){return null!=t&&function(t){return"number"==typeof t&&t>-...
  function Kt (line 2) | function Kt(t){var e=Wt(t)?et.call(t):"";return e==a||e==c}
  function Wt (line 2) | function Wt(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}
  function Zt (line 2) | function Zt(t){return $t(t)?function(t,e){var n=Ht(t)||function(t){retur...
  function P (line 2) | function P(t,e){for(var n=-1,r=null==t?0:t.length;++n<r;)if(e(t[n],n,t))...
  function z (line 2) | function z(t){var e=-1,n=Array(t.size);return t.forEach((function(t,r){n...
  function F (line 2) | function F(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[+...
  function Et (line 2) | function Et(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){va...
  function wt (line 2) | function wt(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){va...
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e=>{document.body.contains(t.root)...
    method addModule (line 2) | addModule(t){const e=super.addModule(t);return"toolbar"===t&&this.exte...
    method buildButtons (line 2) | buildButtons(t,e){Array.from(t).forEach((t=>{(t.getAttribute("class")|...
    method buildPickers (line 2) | buildPickers(t,e){this.pickers=Array.from(t).map((t=>{if(t.classList.c...
  function qt (line 2) | function qt(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){va...
    method constructor (line 2) | constructor(t,e){super(t,e),this.textbox=this.root.querySelector('inpu...
    method listen (line 2) | listen(){this.textbox.addEventListener("keydown",(t=>{"Enter"===t.key?...
    method cancel (line 2) | cancel(){this.hide(),this.restoreFocus()}
    method edit (line 2) | edit(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"l...
    method restoreFocus (line 2) | restoreFocus(){this.quill.focus({preventScroll:!0})}
    method save (line 2) | save(){let{value:t}=this.textbox;switch(this.root.getAttribute("data-m...
  function kt (line 2) | function kt(t){var e=-1,n=null==t?0:t.length;for(this.__data__=new qt;++...
  function _t (line 2) | function _t(t){var e=this.__data__=new wt(t);this.size=e.size}
  function Lt (line 2) | function Lt(t,e){for(var n=t.length;n--;)if(Pt(t[n][0],e))return n;retur...
  function St (line 2) | function St(t){return null==t?void 0===t?w:b:ot&&ot in Object(t)?functio...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.on(bt.A.events.EDITOR_CHANGE,((...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector(".ql-close").addEventL...
    method cancel (line 2) | cancel(){this.show()}
    method position (line 2) | position(t){const e=super.position(t),n=this.root.querySelector(".ql-t...
  function Ot (line 2) | function Ot(t){return Wt(t)&&St(t)==l}
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){this.tooltip=new St(this.quill,this.options.bounds),n...
  function Tt (line 2) | function Tt(t,e,n,r,o){return t===e||(null==t||null==e||!Wt(t)&&!Wt(e)?t...
  function jt (line 2) | function jt(t,e,n,r,o,l){var a=n&i,c=t.length,u=e.length;if(c!=u&&!(a&&u...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector("a.ql-action").addEven...
    method show (line 2) | show(){super.show(),this.root.removeAttribute("data-mode")}
  function Ct (line 2) | function Ct(t){return function(t,e,n){var r=e(t);return Ft(t)?r:function...
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){null!=t.container&&(t.container.classList.add("ql-sno...
  function Rt (line 2) | function Rt(t,e){var n,r,i=t.__data__;return("string"==(r=typeof(n=e))||...
  function It (line 2) | function It(t,e){var n=function(t,e){return null==t?void 0:t[e]}(t,e);re...
  function Ut (line 2) | function Ut(t,e){return!!(e=null==e?o:e)&&("number"==typeof t||S.test(t)...
  function Dt (line 2) | function Dt(t){if(null!=t){try{return X.call(t)}catch(t){}try{return t+"...
  function Pt (line 2) | function Pt(t,e){return t===e||t!=t&&e!=e}
  function $t (line 2) | function $t(t){if(!Kt(t))return!1;var e=St(t);return e==f||e==p||e==c||e...
  function Vt (line 2) | function Vt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=o}
  function Kt (line 2) | function Kt(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}
  function Wt (line 2) | function Wt(t){return null!=t&&"object"==typeof t}
  function Gt (line 2) | function Gt(t){return null!=(e=t)&&Vt(e.length)&&!$t(e)?function(t,e){va...
  class h (line 2) | class h{constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArra...
    method register (line 2) | static register(){c.Ay.register(u)}
    method constructor (line 2) | constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.op...
    method registerEmbed (line 2) | static registerEmbed(t,e){this.handlers[t]=e}
    method unregisterEmbed (line 2) | static unregisterEmbed(t){delete this.handlers[t]}
    method getHandler (line 2) | static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`n...
    method insert (line 2) | insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n....
    method delete (line 2) | delete(t){return t<=0?this:this.push({delete:t})}
    method retain (line 2) | retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t}...
    method push (line 2) | push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==type...
    method chop (line 2) | chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof ...
    method filter (line 2) | filter(t){return this.ops.filter(t)}
    method forEach (line 2) | forEach(t){this.ops.forEach(t)}
    method map (line 2) | map(t){return this.ops.map(t)}
    method partition (line 2) | partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(...
    method reduce (line 2) | reduce(t,e){return this.ops.reduce(t,e)}
    method changeLength (line 2) | changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(...
    method length (line 2) | length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}
    method slice (line 2) | slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i<e...
    method compose (line 2) | compose(t){const e=new a.default(this.ops),n=new a.default(t.ops),r=[]...
    method concat (line 2) | concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.pu...
    method diff (line 2) | diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e....
    method eachLine (line 2) | eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for...
    method invert (line 2) | invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.dele...
    method transform (line 2) | transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPos...
    method transformPosition (line 2) | transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=...
    method formats (line 2) | static formats(t){return this.tagName.indexOf(t.tagName)+1}
  method constructor (line 2) | constructor(t){this.ops=t,this.index=0,this.offset=0}
  method hasNext (line 2) | hasNext(){return this.peekLength()<1/0}
  method next (line 2) | next(t){t||(t=1/0);const e=this.ops[this.index];if(e){const n=this.offse...
  method peek (line 2) | peek(){return this.ops[this.index]}
  method peekLength (line 2) | peekLength(){return this.ops[this.index]?r.default.length(this.ops[this....
  method peekType (line 2) | peekType(){const t=this.ops[this.index];return t?"number"==typeof t.dele...
  method rest (line 2) | rest(){if(this.hasNext()){if(0===this.offset)return this.ops.slice(this....
  function o (line 2) | function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  function o (line 2) | function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  function h (line 2) | function h(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var...
    method register (line 2) | static register(){c.Ay.register(u)}
    method constructor (line 2) | constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.op...
    method registerEmbed (line 2) | static registerEmbed(t,e){this.handlers[t]=e}
    method unregisterEmbed (line 2) | static unregisterEmbed(t){delete this.handlers[t]}
    method getHandler (line 2) | static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`n...
    method insert (line 2) | insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n....
    method delete (line 2) | delete(t){return t<=0?this:this.push({delete:t})}
    method retain (line 2) | retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t}...
    method push (line 2) | push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==type...
    method chop (line 2) | chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof ...
    method filter (line 2) | filter(t){return this.ops.filter(t)}
    method forEach (line 2) | forEach(t){this.ops.forEach(t)}
    method map (line 2) | map(t){return this.ops.map(t)}
    method partition (line 2) | partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(...
    method reduce (line 2) | reduce(t,e){return this.ops.reduce(t,e)}
    method changeLength (line 2) | changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(...
    method length (line 2) | length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}
    method slice (line 2) | slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i<e...
    method compose (line 2) | compose(t){const e=new a.default(this.ops),n=new a.default(t.ops),r=[]...
    method concat (line 2) | concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.pu...
    method diff (line 2) | diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e....
    method eachLine (line 2) | eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for...
    method invert (line 2) | invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.dele...
    method transform (line 2) | transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPos...
    method transformPosition (line 2) | transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=...
    method formats (line 2) | static formats(t){return this.tagName.indexOf(t.tagName)+1}
  function o (line 2) | function o(t){var e=this.__data__=new r.A(t);this.size=e.size}
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  function t (line 2) | function t(){}
  function s (line 2) | function s(t){var e=-1,n=null==t?0:t.length;for(this.__data__=new i.A;++...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  class i (line 2) | class i{constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.T...
    method value (line 2) | static value(){}
    method optimize (line 2) | optimize(){(this.prev||this.next)&&this.remove()}
    method length (line 2) | length(){return 0}
    method value (line 2) | value(){return""}
    method value (line 2) | value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace...
    method constructor (line 2) | constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r....
    method keys (line 2) | static keys(t){return Array.from(t.attributes).map((t=>t.name))}
    method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}
    method canAdd (line 2) | canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whit...
    method remove (line 2) | remove(t){t.removeAttribute(this.keyName)}
    method value (line 2) | value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&...
  class s (line 2) | class s extends Error{constructor(t){super(t="[Parchment] "+t),this.mess...
    method value (line 2) | static value(){}
    method constructor (line 2) | constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document....
    method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this)}
    method format (line 2) | format(t,e){if(0!==this.savedLength)return void super.format(t,e);let ...
    method index (line 2) | index(t,e){return t===this.textNode?0:super.index(t,e)}
    method length (line 2) | length(){return this.savedLength}
    method position (line 2) | position(){return[this.textNode,this.textNode.data.length]}
    method remove (line 2) | remove(){super.remove(),this.parent=null}
    method restore (line 2) | restore(){if(this.selection.composing||null==this.parent)return null;c...
    method update (line 2) | update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.te...
    method optimize (line 2) | optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.d...
    method value (line 2) | value(){return""}
    method constructor (line 2) | constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this...
  method constructor (line 2) | constructor(){this.attributes={},this.classes={},this.tags={},this.types...
  method find (line 2) | static find(t,e=!1){if(null==t)return null;if(this.blots.has(t))return t...
  method create (line 2) | create(e,n,r){const i=this.query(n);if(null==i)throw new s(`Unable to cr...
  method find (line 2) | find(e,n=!1){return t.find(e,n)}
  method query (line 2) | query(t,e=r.ANY){let n;return"string"==typeof t?n=this.types[t]||this.at...
  method register (line 2) | register(...t){return t.map((t=>{const e="blotName"in t,n="attrName"in t...
  function a (line 2) | function a(t,e){return(t.getAttribute("class")||"").split(/\s+/).filter(...
    method constructor (line 2) | constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?argumen...
  method keys (line 2) | static keys(t){return(t.getAttribute("class")||"").split(/\s+/).map((t=>...
  method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(this.remove(t),t.classList.add(`${th...
  method remove (line 2) | remove(t){a(t,this.keyName).forEach((e=>{t.classList.remove(e)})),0===t....
  method value (line 2) | value(t){const e=(a(t,this.keyName)[0]||"").slice(this.keyName.length+1)...
  function u (line 2) | function u(t){const e=t.split("-"),n=e.slice(1).map((t=>t[0].toUpperCase...
    method attach (line 2) | attach(){super.attach(),this.attributes=new r.AttributorStore(this.dom...
    method delta (line 2) | delta(){return(new(s())).insert(this.value(),{...this.formats(),...thi...
    method format (line 2) | format(t,e){const n=this.scroll.query(t,r.Scope.BLOCK_ATTRIBUTE);null!...
    method formatAt (line 2) | formatAt(t,e,n,r){this.format(n,r)}
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return void super.insertAt(t,e,n);const r=e...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("spellc...
    method code (line 2) | code(t,e){return this.children.map((t=>t.length()<=1?"":t.domNode.inne...
    method html (line 2) | html(t,e){return`<pre>\n${(0,l.X)(this.code(t,e))}\n</pre>`}
  method keys (line 2) | static keys(t){return(t.getAttribute("style")||"").split(";").map((t=>t....
  method add (line 2) | add(t,e){return!!this.canAdd(t,e)&&(t.style[u(this.keyName)]=e,!0)}
  method remove (line 2) | remove(t){t.style[u(this.keyName)]="",t.getAttribute("style")||t.removeA...
  method value (line 2) | value(t){const e=t.style[u(this.keyName)];return this.canAdd(t,e)?e:""}
  method constructor (line 2) | constructor(t){this.attributes={},this.domNode=t,this.build()}
  method attribute (line 2) | attribute(t,e){e?t.add(this.domNode,e)&&(null!=t.value(this.domNode)?thi...
  method build (line 2) | build(){this.attributes={};const t=l.find(this.domNode);if(null==t)retur...
  method copy (line 2) | copy(t){Object.keys(this.attributes).forEach((e=>{const n=this.attribute...
  method move (line 2) | move(t){this.copy(t),Object.keys(this.attributes).forEach((t=>{this.attr...
  method values (line 2) | values(){return Object.keys(this.attributes).reduce(((t,e)=>(t[e]=this.a...
  method constructor (line 2) | constructor(t,e){this.scroll=t,this.domNode=e,l.blots.set(e,this),this.p...
  method create (line 2) | static create(t){if(null==this.tagName)throw new s("Blot definition miss...
  method statics (line 2) | get statics(){return this.constructor}
  method attach (line 2) | attach(){}
  method clone (line 2) | clone(){const t=this.domNode.cloneNode(!1);return this.scroll.create(t)}
  method detach (line 2) | detach(){null!=this.parent&&this.parent.removeChild(this),l.blots.delete...
  method deleteAt (line 2) | deleteAt(t,e){this.isolate(t,e).remove()}
  method formatAt (line 2) | formatAt(t,e,n,i){const s=this.isolate(t,e);if(null!=this.scroll.query(n...
  method insertAt (line 2) | insertAt(t,e,n){const r=null==n?this.scroll.create("text",e):this.scroll...
  method isolate (line 2) | isolate(t,e){const n=this.split(t);if(null==n)throw new Error("Attempt t...
  method length (line 2) | length(){return 1}
  method offset (line 2) | offset(t=this.parent){return null==this.parent||this===t?0:this.parent.c...
  method optimize (line 2) | optimize(t){this.statics.requiredContainer&&!(this.parent instanceof thi...
  method remove (line 2) | remove(){null!=this.domNode.parentNode&&this.domNode.parentNode.removeCh...
  method replaceWith (line 2) | replaceWith(t,e){const n="string"==typeof t?this.scroll.create(t,e):t;re...
  method split (line 2) | split(t,e){return 0===t?this:this.next}
  method update (line 2) | update(t,e){}
  method wrap (line 2) | wrap(t,e){const n="string"==typeof t?this.scroll.create(t,e):t;if(null!=...
  method value (line 2) | static value(t){return!0}
  method index (line 2) | index(t,e){return this.domNode===t||this.domNode.compareDocumentPosition...
  method position (line 2) | position(t,e){let n=Array.from(this.parent.domNode.childNodes).indexOf(t...
  method value (line 2) | value(){return{[this.statics.blotName]:this.statics.value(this.domNode)|...
  class b (line 2) | class b{constructor(){this.head=null,this.tail=null,this.length=0}append...
    method constructor (line 2) | constructor(){this.head=null,this.tail=null,this.length=0}
    method append (line 2) | append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.sli...
    method at (line 2) | at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}
    method contains (line 2) | contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return...
    method indexOf (line 2) | indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)ret...
    method insertBefore (line 2) | insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e....
    method offset (line 2) | offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.le...
    method remove (line 2) | remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=...
    method iterator (line 2) | iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}
    method find (line 2) | find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.leng...
    method forEach (line 2) | forEach(t){const e=this.iterator();let n=e();for(;n;)t(n),n=e()}
    method forEachAt (line 2) | forEachAt(t,e,n){if(e<=0)return;const[r,i]=this.find(t);let s=t-i;cons...
    method map (line 2) | map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}
    method reduce (line 2) | reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();r...
  function y (line 2) | function y(t,e){const n=e.find(t);if(n)return n;try{return e.create(t)}c...
  method constructor (line 2) | constructor(t,e){super(t,e),this.uiNode=null,this.build()}
  method appendChild (line 2) | appendChild(t){this.insertBefore(t)}
  method attach (line 2) | attach(){super.attach(),this.children.forEach((t=>{t.attach()}))}
  method attachUI (line 2) | attachUI(e){null!=this.uiNode&&this.uiNode.remove(),this.uiNode=e,t.uiCl...
  method build (line 2) | build(){this.children=new b,Array.from(this.domNode.childNodes).filter((...
  method deleteAt (line 2) | deleteAt(t,e){if(0===t&&e===this.length())return this.remove();this.chil...
  method descendant (line 2) | descendant(e,n=0){const[r,i]=this.children.find(n);return null==e.blotNa...
  method descendants (line 2) | descendants(e,n=0,r=Number.MAX_VALUE){let i=[],s=r;return this.children....
  method detach (line 2) | detach(){this.children.forEach((t=>{t.detach()})),super.detach()}
  method enforceAllowedChildren (line 2) | enforceAllowedChildren(){let e=!1;this.children.forEach((n=>{e||this.sta...
  method formatAt (line 2) | formatAt(t,e,n,r){this.children.forEachAt(t,e,((t,e,i)=>{t.formatAt(e,i,...
  method insertAt (line 2) | insertAt(t,e,n){const[r,i]=this.children.find(t);if(r)r.insertAt(i,e,n);...
  method insertBefore (line 2) | insertBefore(t,e){null!=t.parent&&t.parent.children.remove(t);let n=null...
  method length (line 2) | length(){return this.children.reduce(((t,e)=>t+e.length()),0)}
  method moveChildren (line 2) | moveChildren(t,e){this.children.forEach((n=>{t.insertBefore(n,e)}))}
  method optimize (line 2) | optimize(t){if(super.optimize(t),this.enforceAllowedChildren(),null!=thi...
  method path (line 2) | path(e,n=!1){const[r,i]=this.children.find(e,n),s=[[this,e]];return r in...
  method removeChild (line 2) | removeChild(t){this.children.remove(t)}
  method replaceWith (line 2) | replaceWith(e,n){const r="string"==typeof e?this.scroll.create(e,n):e;re...
  method split (line 2) | split(t,e=!1){if(!e){if(0===t)return this;if(t===this.length())return th...
  method splitAfter (line 2) | splitAfter(t){const e=this.clone();for(;null!=t.next;)e.appendChild(t.ne...
  method unwrap (line 2) | unwrap(){this.parent&&this.moveChildren(this.parent,this.next||void 0),t...
  method update (line 2) | update(t,e){const n=[],r=[];t.forEach((t=>{t.target===this.domNode&&"chi...
  method create (line 2) | static create(t){return super.create(t)}
  method formats (line 2) | static formats(e,n){const r=n.query(t.blotName);if(null==r||e.tagName!==...
  method constructor (line 2) | constructor(t,e){super(t,e),this.attributes=new d(this.domNode)}
  method format (line 2) | format(e,n){if(e!==this.statics.blotName||n){const t=this.scroll.query(e...
  method formats (line 2) | formats(){const t=this.attributes.values(),e=this.statics.formats(this.d...
  method formatAt (line 2) | formatAt(t,e,n,i){null!=this.formats()[n]||this.scroll.query(n,r.ATTRIBU...
  method optimize (line 2) | optimize(e){super.optimize(e);const n=this.formats();if(0===Object.keys(...
  method replaceWith (line 2) | replaceWith(t,e){const n=super.replaceWith(t,e);return this.attributes.c...
  method update (line 2) | update(t,e){super.update(t,e),t.some((t=>t.target===this.domNode&&"attri...
  method wrap (line 2) | wrap(e,n){const r=super.wrap(e,n);return r instanceof t&&this.attributes...
  method create (line 2) | static create(t){return super.create(t)}
  method formats (line 2) | static formats(e,n){const r=n.query(t.blotName);if(null==r||e.tagName!==...
  method constructor (line 2) | constructor(t,e){super(t,e),this.attributes=new d(this.domNode)}
  method format (line 2) | format(e,n){const s=this.scroll.query(e,r.BLOCK);null!=s&&(s instanceof ...
  method formats (line 2) | formats(){const t=this.attributes.values(),e=this.statics.formats(this.d...
  method formatAt (line 2) | formatAt(t,e,n,i){null!=this.scroll.query(n,r.BLOCK)?this.format(n,i):su...
  method insertAt (line 2) | insertAt(t,e,n){if(null==n||null!=this.scroll.query(e,r.INLINE))super.in...
  method replaceWith (line 2) | replaceWith(t,e){const n=super.replaceWith(t,e);return this.attributes.c...
  method update (line 2) | update(t,e){super.update(t,e),t.some((t=>t.target===this.domNode&&"attri...
  method checkMerge (line 2) | checkMerge(){return null!==this.next&&this.next.statics.blotName===this....
  method deleteAt (line 2) | deleteAt(t,e){super.deleteAt(t,e),this.enforceAllowedChildren()}
  method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.enforceAllowedChildren()}
  method insertAt (line 2) | insertAt(t,e,n){super.insertAt(t,e,n),this.enforceAllowedChildren()}
  method optimize (line 2) | optimize(t){super.optimize(t),this.children.length>0&&null!=this.next&&t...
  method formats (line 2) | static formats(t,e){}
  method format (line 2) | format(t,e){super.formatAt(0,this.length(),t,e)}
  method formatAt (line 2) | formatAt(t,e,n,r){0===t&&e===this.length()?this.format(n,r):super.format...
  method formats (line 2) | formats(){return this.statics.formats(this.domNode,this.scroll)}
  method constructor (line 2) | constructor(t,e){super(null,e),this.registry=t,this.scroll=this,this.bui...
  method create (line 2) | create(t,e){return this.registry.create(this,t,e)}
  method find (line 2) | find(t,e=!1){const n=this.registry.find(t,e);return n?n.scroll===this?n:...
  method query (line 2) | query(t,e=r.ANY){return this.registry.query(t,e)}
  method register (line 2) | register(...t){return this.registry.register(...t)}
  method build (line 2) | build(){null!=this.scroll&&super.build()}
  method detach (line 2) | detach(){super.detach(),this.observer.disconnect()}
  method deleteAt (line 2) | deleteAt(t,e){this.update(),0===t&&e===this.length()?this.children.forEa...
  method formatAt (line 2) | formatAt(t,e,n,r){this.update(),super.formatAt(t,e,n,r)}
  method insertAt (line 2) | insertAt(t,e,n){this.update(),super.insertAt(t,e,n)}
  method optimize (line 2) | optimize(t=[],e={}){super.optimize(e);const n=e.mutationsMap||new WeakMa...
  method update (line 2) | update(t,e={}){t=t||this.observer.takeRecords();const n=new WeakMap;t.ma...
  method create (line 2) | static create(t){return document.createTextNode(t)}
  method value (line 2) | static value(t){return t.data}
  method constructor (line 2) | constructor(t,e){super(t,e),this.text=this.statics.value(this.domNode)}
  method deleteAt (line 2) | deleteAt(t,e){this.domNode.data=this.text=this.text.slice(0,t)+this.text...
  method index (line 2) | index(t,e){return this.domNode===t?e:-1}
  method insertAt (line 2) | insertAt(t,e,n){null==n?(this.text=this.text.slice(0,t)+e+this.text.slic...
  method length (line 2) | length(){return this.text.length}
  method optimize (line 2) | optimize(e){super.optimize(e),this.text=this.statics.value(this.domNode)...
  method position (line 2) | position(t,e=!1){return[this.domNode,t]}
  method split (line 2) | split(t,e=!1){if(!e){if(0===t)return this;if(t===this.length())return th...
  method update (line 2) | update(t,e){t.some((t=>"characterData"===t.type&&t.target===this.domNode...
  method value (line 2) | value(){return this.text}
  function n (line 2) | function n(r){var i=e[r];if(void 0!==i)return i.exports;var s=e[r]={id:r...
    method constructor (line 2) | constructor(t,e){this.quill=t,this.options=e}
    method init (line 2) | init(){Object.keys(this.options.modules).forEach((t=>{null==this.modul...
    method addModule (line 2) | addModule(t){const e=this.quill.constructor.import(`modules/${t}`);ret...
  class o (line 2) | class o extends s.ClassAttributor{add(t,e){let n=0;if("+1"===e||"-1"===e...
    method constructor (line 2) | constructor(t,e){super(t,e),this.contentNode=document.createElement("s...
    method index (line 2) | index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.ind...
    method restore (line 2) | restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.l...
    method update (line 2) | update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===th...
    method compare (line 2) | static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);re...
    method formatAt (line 2) | formatAt(t,e,n,i){if(o.compare(this.statics.blotName,n)<0&&this.scroll...
    method optimize (line 2) | optimize(t){if(super.optimize(t),this.parent instanceof o&&o.compare(t...
    method value (line 2) | value(t){return super.value(t).replace(/["']/g,"")}
    method add (line 2) | add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1...
    method canAdd (line 2) | canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}
    method value (line 2) | value(t){return parseInt(super.value(t),10)||void 0}
  class c (line 2) | class c extends a.Ay{static blotName="blockquote";static tagName="blockq...
    method delta (line 2) | delta(){return null==this.cache.delta&&(this.cache.delta=h(this)),this...
    method deleteAt (line 2) | deleteAt(t,e){super.deleteAt(t,e),this.cache={}}
    method formatAt (line 2) | formatAt(t,e,n,i){e<=0||(this.scroll.query(n,r.Scope.BLOCK)?t+e===this...
    method insertAt (line 2) | insertAt(t,e,n){if(null!=n)return super.insertAt(t,e,n),void(this.cach...
    method insertBefore (line 2) | insertBefore(t,e){const{head:n}=this.children;super.insertBefore(t,e),...
    method length (line 2) | length(){return null==this.cache.length&&(this.cache.length=super.leng...
    method moveChildren (line 2) | moveChildren(t,e){super.moveChildren(t,e),this.cache={}}
    method optimize (line 2) | optimize(t){super.optimize(t),this.cache={}}
    method path (line 2) | path(t){return super.path(t,!0)}
    method removeChild (line 2) | removeChild(t){super.removeChild(t),this.cache={}}
    method split (line 2) | split(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1]...
  class h (line 2) | class h extends a.Ay{static blotName="header";static tagName=["H1","H2",...
    method register (line 2) | static register(){c.Ay.register(u)}
    method constructor (line 2) | constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.op...
    method registerEmbed (line 2) | static registerEmbed(t,e){this.handlers[t]=e}
    method unregisterEmbed (line 2) | static unregisterEmbed(t){delete this.handlers[t]}
    method getHandler (line 2) | static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`n...
    method insert (line 2) | insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n....
    method delete (line 2) | delete(t){return t<=0?this:this.push({delete:t})}
    method retain (line 2) | retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t}...
    method push (line 2) | push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==type...
    method chop (line 2) | chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof ...
    method filter (line 2) | filter(t){return this.ops.filter(t)}
    method forEach (line 2) | forEach(t){this.ops.forEach(t)}
    method map (line 2) | map(t){return this.ops.map(t)}
    method partition (line 2) | partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(...
    method reduce (line 2) | reduce(t,e){return this.ops.reduce(t,e)}
    method changeLength (line 2) | changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(...
    method length (line 2) | length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}
    method slice (line 2) | slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i<e...
    method compose (line 2) | compose(t){const e=new a.default(this.ops),n=new a.default(t.ops),r=[]...
    method concat (line 2) | concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.pu...
    method diff (line 2) | diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e....
    method eachLine (line 2) | eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for...
    method invert (line 2) | invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.dele...
    method transform (line 2) | transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPos...
    method transformPosition (line 2) | transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=...
    method formats (line 2) | static formats(t){return this.tagName.indexOf(t.tagName)+1}
  class g (line 2) | class g extends f.A{}
  class m (line 2) | class m extends a.Ay{static create(t){const e=super.create();return e.se...
    method constructor (line 2) | constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.bat...
    method batchStart (line 2) | batchStart(){Array.isArray(this.batch)||(this.batch=[])}
    method batchEnd (line 2) | batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this...
    method emitMount (line 2) | emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}
    method emitUnmount (line 2) | emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}
    method emitEmbedUpdate (line 2) | emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,...
    method deleteAt (line 2) | deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.dele...
    method enable (line 2) | enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments...
    method formatAt (line 2) | formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}
    method insertAt (line 2) | insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.quer...
    method insertBefore (line 2) | insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=th...
    method insertContents (line 2) | insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d()...
    method isEnabled (line 2) | isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}
    method leaf (line 2) | leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;...
    method line (line 2) | line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}
    method lines (line 2) | lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0...
    method optimize (line 2) | optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method path (line 2) | path(t){return super.path(t).slice(1)}
    method remove (line 2) | remove(){}
    method update (line 2) | update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this...
    method updateEmbedAt (line 2) | updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t...
    method handleDragStart (line 2) | handleDragStart(t){t.preventDefault()}
    method deltaToRenderBlocks (line 2) | deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>...
    method createBlock (line 2) | createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e...
    method create (line 2) | static create(t){const e=super.create();return e.setAttribute("data-li...
    method formats (line 2) | static formats(t){return t.getAttribute("data-list")||void 0}
    method register (line 2) | static register(){p.Ay.register(g)}
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("spa...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
  class N (line 2) | class N extends x.A{static blotName="bold";static tagName=["STRONG","B"]...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.on(r.Ay.events.EDITOR_CHANGE,((...
    method change (line 2) | change(t,e){if(0===this.stack[t].length)return;const n=this.stack[t].p...
    method clear (line 2) | clear(){this.stack={undo:[],redo:[]}}
    method cutoff (line 2) | cutoff(){this.lastRecorded=0}
    method record (line 2) | record(t,e){if(0===t.ops.length)return;this.stack.redo=[];let n=t.inve...
    method redo (line 2) | redo(){this.change("redo","undo")}
    method transform (line 2) | transform(t){E(this.stack.undo,t),E(this.stack.redo,t)}
    method undo (line 2) | undo(){this.change("undo","redo")}
    method restoreSelection (line 2) | restoreSelection(t){if(t.range)this.quill.setSelection(t.range,r.Ay.so...
    method create (line 2) | static create(){return super.create()}
    method formats (line 2) | static formats(){return!0}
    method optimize (line 2) | optimize(t){super.optimize(t),this.domNode.tagName!==this.statics.tagN...
  class w (line 2) | class w extends x.A{static blotName="link";static tagName="A";static SAN...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("href",...
    method formats (line 2) | static formats(t){return t.getAttribute("href")}
    method sanitize (line 2) | static sanitize(t){return q(t,this.PROTOCOL_WHITELIST)?t:this.SANITIZE...
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("hr...
  function q (line 2) | function q(t,e){const n=document.createElement("a");n.href=t;const r=n.h...
  class k (line 2) | class k extends x.A{static blotName="script";static tagName=["SUB","SUP"...
    method constructor (line 2) | constructor(t,e){super(t,e),t.root.addEventListener("drop",(e=>{e.prev...
    method upload (line 2) | upload(t,e){const n=[];Array.from(e).forEach((t=>{t&&this.options.mime...
    method create (line 2) | static create(t){return"super"===t?document.createElement("sup"):"sub"...
    method formats (line 2) | static formats(t){return"SUB"===t.tagName?"sub":"SUP"===t.tagName?"sup...
  class L (line 2) | class L extends x.A{static blotName="underline";static tagName="U"}
  class T (line 2) | class T extends O.A{static blotName="formula";static className="ql-formu...
    method create (line 2) | static create(t){if(null==window.katex)throw new Error("Formula module...
    method value (line 2) | static value(t){return t.getAttribute("data-value")}
    method html (line 2) | html(){const{formula:t}=this.value();return`<span>${t}</span>`}
  class R (line 2) | class R extends s.EmbedBlot{static blotName="image";static tagName="IMG"...
    method create (line 2) | static create(t){const e=super.create(t);return"string"==typeof t&&e.s...
    method formats (line 2) | static formats(t){return C.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t....
    method match (line 2) | static match(t){return/\.(jpe?g|gif|png)$/.test(t)||/^data:image\/.+;b...
    method sanitize (line 2) | static sanitize(t){return q(t,["http","https","data"])?t:"//:0"}
    method value (line 2) | static value(t){return t.getAttribute("src")}
    method format (line 2) | format(t,e){C.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domN...
  class M (line 2) | class M extends a.zo{static blotName="video";static className="ql-video"...
    method create (line 2) | static create(t){const e=super.create(t);return e.setAttribute("frameb...
    method formats (line 2) | static formats(t){return B.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t....
    method sanitize (line 2) | static sanitize(t){return w.sanitize(t)}
    method value (line 2) | static value(t){return t.getAttribute("src")}
    method format (line 2) | format(t,e){B.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domN...
    method html (line 2) | html(){const{video:t}=this.value();return`<a href="${t}">${t}</a>`}
  class Z (line 2) | class Z extends x.A{static formats(t,e){for(;null!=t&&t!==e.domNode;){if...
    method formats (line 2) | static formats(t,e){for(;null!=t&&t!==e.domNode;){if(t.classList&&t.cl...
    method constructor (line 2) | constructor(t,e,n){super(t,e,n),W.add(this.domNode,n)}
    method format (line 2) | format(t,e){t!==Z.blotName?super.format(t,e):e?W.add(this.domNode,e):(...
    method optimize (line 2) | optimize(){super.optimize(...arguments),W.value(this.domNode)||this.un...
  class G (line 2) | class G extends D.Ay{static create(t){const e=super.create(t);return"str...
    method create (line 2) | static create(t){const e=super.create(t);return"string"==typeof t&&e.s...
    method formats (line 2) | static formats(t){return t.getAttribute("data-language")||"plain"}
    method register (line 2) | static register(){}
    method format (line 2) | format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("da...
    method replaceWith (line 2) | replaceWith(t,e){return this.formatAt(0,this.length(),Z.blotName,!1),s...
  class X (line 2) | class X extends D.EJ{attach(){super.attach(),this.forceNext=!1,this.scro...
    method attach (line 2) | attach(){super.attach(),this.forceNext=!1,this.scroll.emitMount(this)}
    method format (line 2) | format(t,e){t===G.blotName&&(this.forceNext=!0,this.children.forEach((...
    method formatAt (line 2) | formatAt(t,e,n,r){n===G.blotName&&(this.forceNext=!0),super.formatAt(t...
    method highlight (line 2) | highlight(t){let e=arguments.length>1&&void 0!==arguments[1]&&argument...
    method html (line 2) | html(t,e){const[n]=this.children.find(t);return`<pre data-language="${...
    method optimize (line 2) | optimize(t){if(super.optimize(t),null!=this.parent&&null!=this.childre...
  class Q (line 2) | class Q extends F.A{static register(){p.Ay.register(Z,!0),p.Ay.register(...
    method register (line 2) | static register(){p.Ay.register(Z,!0),p.Ay.register(G,!0),p.Ay.registe...
    method constructor (line 2) | constructor(t,e){if(super(t,e),null==this.options.hljs)throw new Error...
    method initListener (line 2) | initListener(){this.quill.on(p.Ay.events.SCROLL_BLOT_MOUNT,(t=>{if(!(t...
    method initTimer (line 2) | initTimer(){let t=null;this.quill.on(p.Ay.events.SCROLL_OPTIMIZE,(()=>...
    method highlight (line 2) | highlight(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[...
    method highlightBlot (line 2) | highlightBlot(t){let e=arguments.length>1&&void 0!==arguments[1]?argum...
  class J (line 2) | class J extends a.Ay{static blotName="table";static tagName="TD";static ...
    method create (line 2) | static create(t){const e=super.create();return t?e.setAttribute("data-...
    method formats (line 2) | static formats(t){if(t.hasAttribute("data-row"))return t.getAttribute(...
    method cellOffset (line 2) | cellOffset(){return this.parent?this.parent.children.indexOf(this):-1}
    method format (line 2) | format(t,e){t===J.blotName&&e?this.domNode.setAttribute("data-row",e):...
    method row (line 2) | row(){return this.parent}
    method rowOffset (line 2) | rowOffset(){return this.row()?this.row().rowOffset():-1}
    method table (line 2) | table(){return this.row()&&this.row().table()}
  class Y (line 2) | class Y extends f.A{static blotName="table-row";static tagName="TR";chec...
    method checkMerge (line 2) | checkMerge(){if(super.checkMerge()&&null!=this.next.children.head){con...
    method optimize (line 2) | optimize(t){super.optimize(t),this.children.forEach((t=>{if(null==t.ne...
    method rowOffset (line 2) | rowOffset(){return this.parent?this.parent.children.indexOf(this):-1}
    method table (line 2) | table(){return this.parent&&this.parent.parent}
  class tt (line 2) | class tt extends f.A{static blotName="table-body";static tagName="TBODY"}
  class et (line 2) | class et extends f.A{static blotName="table-container";static tagName="T...
    method balanceCells (line 2) | balanceCells(){const t=this.descendants(Y),e=t.reduce(((t,e)=>Math.max...
    method cells (line 2) | cells(t){return this.rows().map((e=>e.children.at(t)))}
    method deleteColumn (line 2) | deleteColumn(t){const[e]=this.descendant(tt);null!=e&&null!=e.children...
    method insertColumn (line 2) | insertColumn(t){const[e]=this.descendant(tt);null!=e&&null!=e.children...
    method insertRow (line 2) | insertRow(t){const[e]=this.descendant(tt);if(null==e||null==e.children...
    method rows (line 2) | rows(){const t=this.children.head;return null==t?[]:t.children.map((t=...
  function nt (line 2) | function nt(){return`row-${Math.random().toString(36).slice(2,6)}`}
  class rt (line 2) | class rt extends F.A{static register(){p.Ay.register(J),p.Ay.register(Y)...
    method register (line 2) | static register(){p.Ay.register(J),p.Ay.register(Y),p.Ay.register(tt),...
    method constructor (line 2) | constructor(){super(...arguments),this.listenBalanceCells()}
    method balanceTables (line 2) | balanceTables(){this.quill.scroll.descendants(et).forEach((t=>{t.balan...
    method deleteColumn (line 2) | deleteColumn(){const[t,,e]=this.getTable();null!=e&&(t.deleteColumn(e....
    method deleteRow (line 2) | deleteRow(){const[,t]=this.getTable();null!=t&&(t.remove(),this.quill....
    method deleteTable (line 2) | deleteTable(){const[t]=this.getTable();if(null==t)return;const e=t.off...
    method getTable (line 2) | getTable(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0...
    method insertColumn (line 2) | insertColumn(t){const e=this.quill.getSelection();if(!e)return;const[n...
    method insertColumnLeft (line 2) | insertColumnLeft(){this.insertColumn(0)}
    method insertColumnRight (line 2) | insertColumnRight(){this.insertColumn(1)}
    method insertRow (line 2) | insertRow(t){const e=this.quill.getSelection();if(!e)return;const[n,r,...
    method insertRowAbove (line 2) | insertRowAbove(){this.insertRow(0)}
    method insertRowBelow (line 2) | insertRowBelow(){this.insertRow(1)}
    method insertTable (line 2) | insertTable(t,e){const n=this.quill.getSelection();if(null==n)return;c...
    method listenBalanceCells (line 2) | listenBalanceCells(){this.quill.on(p.Ay.events.SCROLL_OPTIMIZE,(t=>{t....
  class ot (line 2) | class ot extends F.A{constructor(t,e){if(super(t,e),Array.isArray(this.o...
    method constructor (line 2) | constructor(t,e){if(super(t,e),Array.isArray(this.options.container)){...
    method addHandler (line 2) | addHandler(t,e){this.handlers[t]=e}
    method attach (line 2) | attach(t){let e=Array.from(t.classList).find((t=>0===t.indexOf("ql-"))...
    method update (line 2) | update(t){const e=null==t?{}:this.quill.getFormat(t);this.controls.for...
  function lt (line 2) | function lt(t,e,n){const r=document.createElement("button");r.setAttribu...
  method clean (line 2) | clean(){const t=this.quill.getSelection();if(null!=t)if(0===t.length){co...
  method direction (line 2) | direction(t){const{align:e}=this.quill.getFormat();"rtl"===t&&null==e?th...
  method indent (line 2) | indent(t){const e=this.quill.getSelection(),n=this.quill.getFormat(e),r=...
  method link (line 2) | link(t){!0===t&&(t=prompt("Enter link URL:")),this.quill.format("link",t...
  method list (line 2) | list(t){const e=this.quill.getSelection(),n=this.quill.getFormat(e);"che...
  function ht (line 2) | function ht(t,e){t.setAttribute(e,`${!("true"===t.getAttribute(e))}`)}
  method constructor (line 2) | constructor(t){this.select=t,this.container=document.createElement("span...
  method togglePicker (line 2) | togglePicker(){this.container.classList.toggle("ql-expanded"),ht(this.la...
  method buildItem (line 2) | buildItem(t){const e=document.createElement("span");e.tabIndex="0",e.set...
  method buildLabel (line 2) | buildLabel(){const t=document.createElement("span");return t.classList.a...
  method buildOptions (line 2) | buildOptions(){const t=document.createElement("span");t.classList.add("q...
  method buildPicker (line 2) | buildPicker(){Array.from(this.select.attributes).forEach((t=>{this.conta...
  method escape (line 2) | escape(){this.close(),setTimeout((()=>this.label.focus()),1)}
  method close (line 2) | close(){this.container.classList.remove("ql-expanded"),this.label.setAtt...
  method selectItem (line 2) | selectItem(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments...
  method update (line 2) | update(){let t;if(this.select.selectedIndex>-1){const e=this.container.q...
  method constructor (line 2) | constructor(t,e){super(t),this.label.innerHTML=e,this.container.classLis...
  method buildItem (line 2) | buildItem(t){const e=super.buildItem(t);return e.style.backgroundColor=t...
  method selectItem (line 2) | selectItem(t,e){super.selectItem(t,e);const n=this.label.querySelector("...
  method constructor (line 2) | constructor(t,e){super(t),this.container.classList.add("ql-icon-picker")...
  method selectItem (line 2) | selectItem(t,e){super.selectItem(t,e);const n=t||this.defaultItem;if(nul...
  method constructor (line 2) | constructor(t,e){this.quill=t,this.boundsContainer=e||document.body,this...
  method hide (line 2) | hide(){this.root.classList.add("ql-hidden")}
  method position (line 2) | position(t){const e=t.left+t.width/2-this.root.offsetWidth/2,n=t.bottom+...
  method show (line 2) | show(){this.root.classList.remove("ql-editing"),this.root.classList.remo...
  class wt (line 2) | class wt extends yt.A{constructor(t,e){super(t,e);const n=e=>{document.b...
    method constructor (line 2) | constructor(t,e){super(t,e);const n=e=>{document.body.contains(t.root)...
    method addModule (line 2) | addModule(t){const e=super.addModule(t);return"toolbar"===t&&this.exte...
    method buildButtons (line 2) | buildButtons(t,e){Array.from(t).forEach((t=>{(t.getAttribute("class")|...
    method buildPickers (line 2) | buildPickers(t,e){this.pickers=Array.from(t).map((t=>{if(t.classList.c...
  method formula (line 2) | formula(){this.quill.theme.tooltip.edit("formula")}
  method image (line 2) | image(){let t=this.container.querySelector("input.ql-image[type=file]");...
  method video (line 2) | video(){this.quill.theme.tooltip.edit("video")}
  class qt (line 2) | class qt extends gt{constructor(t,e){super(t,e),this.textbox=this.root.q...
    method constructor (line 2) | constructor(t,e){super(t,e),this.textbox=this.root.querySelector('inpu...
    method listen (line 2) | listen(){this.textbox.addEventListener("keydown",(t=>{"Enter"===t.key?...
    method cancel (line 2) | cancel(){this.hide(),this.restoreFocus()}
    method edit (line 2) | edit(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"l...
    method restoreFocus (line 2) | restoreFocus(){this.quill.focus({preventScroll:!0})}
    method save (line 2) | save(){let{value:t}=this.textbox;switch(this.root.getAttribute("data-m...
  function kt (line 2) | function kt(t,e){let n=arguments.length>2&&void 0!==arguments[2]&&argume...
  class St (line 2) | class St extends qt{static TEMPLATE=['<span class="ql-tooltip-arrow"></s...
    method constructor (line 2) | constructor(t,e){super(t,e),this.quill.on(bt.A.events.EDITOR_CHANGE,((...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector(".ql-close").addEventL...
    method cancel (line 2) | cancel(){this.show()}
    method position (line 2) | position(t){const e=super.position(t),n=this.root.querySelector(".ql-t...
  class Ot (line 2) | class Ot extends wt{constructor(t,e){null!=e.modules.toolbar&&null==e.mo...
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){this.tooltip=new St(this.quill,this.options.bounds),n...
  method link (line 2) | link(t){t?this.quill.theme.tooltip.edit():this.quill.format("link",!1,p....
  class jt (line 2) | class jt extends qt{static TEMPLATE=['<a class="ql-preview" rel="noopene...
    method listen (line 2) | listen(){super.listen(),this.root.querySelector("a.ql-action").addEven...
    method show (line 2) | show(){super.show(),this.root.removeAttribute("data-mode")}
  class Ct (line 2) | class Ct extends wt{constructor(t,e){null!=e.modules.toolbar&&null==e.mo...
    method constructor (line 2) | constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.cont...
    method extendToolbar (line 2) | extendToolbar(t){null!=t.container&&(t.container.classList.add("ql-sno...
  method link (line 2) | link(t){if(t){const t=this.quill.getSelection();if(null==t||0===t.length...

FILE: assets/vendor/quill/quill.module.wordcount.js
  function e (line 3) | function e(r){if(t[r])return t[r].exports;var o=t[r]={exports:{}};return...
  function e (line 3) | function e(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={expo...
  function r (line 3) | function r(n){return(new Intl.NumberFormat).format(n)}
  function o (line 3) | function o(n,t,e){const o=document.createElement("i");return o.className...
  function i (line 3) | function i(n){const{l10n:t,min:e,max:r}=n,i=document.createElement("div"...
  function u (line 3) | function u(n,t){const{min:e,max:r,colorWarning:o,colorError:i}=t;let u="...
  function l (line 3) | function l(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0...
  function a (line 3) | function a(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[...

FILE: assets/vendor/select2/js/select2.js
  function hasProp (line 84) | function hasProp(obj, prop) {
  function normalize (line 96) | function normalize(name, baseName) {
  function makeRequire (line 206) | function makeRequire(relName, forceSync) {
  function makeNormalize (line 223) | function makeNormalize(relName) {
  function makeLoad (line 229) | function makeLoad(depName) {
  function callDep (line 235) | function callDep(name) {
  function splitPrefix (line 252) | function splitPrefix(name) {
  function makeRelParts (line 264) | function makeRelParts(relName) {
  function makeConfig (line 312) | function makeConfig(name) {
  function BaseConstructor (line 528) | function BaseConstructor () {
  function getMethods (line 545) | function getMethods (theClass) {
  function DecoratedClass (line 571) | function DecoratedClass () {
  function ctr (line 589) | function ctr () {
  function Results (line 865) | function Results ($element, options, dataAdapter) {
  function BaseSelection (line 1428) | function BaseSelection ($element, options) {
  function SingleSelection (line 1608) | function SingleSelection () {
  function MultipleSelection (line 1715) | function MultipleSelection ($element, options) {
  function Placeholder (line 1830) | function Placeholder (decorated, $element, options) {
  function AllowClear (line 1882) | function AllowClear () { }
  function Search (line 1996) | function Search (decorated, $element, options) {
  function EventRelay (line 2231) | function EventRelay () { }
  function Translation (line 2281) | function Translation (dict) {
  function BaseAdapter (line 3168) | function BaseAdapter ($element, options) {
  function SelectAdapter (line 3211) | function SelectAdapter ($element, options) {
  function ArrayAdapter (line 3497) | function ArrayAdapter ($element, options) {
  function onlyItem (line 3536) | function onlyItem (item) {
  function AjaxAdapter (line 3581) | function AjaxAdapter ($element, options) {
  function request (line 3642) | function request () {
  function Tags (line 3690) | function Tags (decorated, $element, options) {
  function wrapper (line 3729) | function wrapper (obj, child) {
  function Tokenizer (line 3817) | function Tokenizer (decorated, $element, options) {
  function createAndSelect (line 3837) | function createAndSelect (data) {
  function select (line 3860) | function select (data) {
  function MinimumInputLength (line 3934) | function MinimumInputLength (decorated, $e, options) {
  function MaximumInputLength (line 3965) | function MaximumInputLength (decorated, $e, options) {
  function MaximumSelectionLength (line 3997) | function MaximumSelectionLength (decorated, $e, options) {
  function Dropdown (line 4053) | function Dropdown ($element, options) {
  function Search (line 4096) | function Search () { }
  function HidePlaceholder (line 4211) | function HidePlaceholder (decorated, $element, options, dataAdapter) {
  function InfiniteScroll (line 4254) | function InfiniteScroll (decorated, $element, options, dataAdapter) {
  function AttachBody (line 4348) | function AttachBody (decorated, $element, options) {
  function countResults (line 4605) | function countResults (data) {
  function MinimumResultsForSearch (line 4621) | function MinimumResultsForSearch (decorated, $element, options, dataAdap...
  function SelectOnClose (line 4645) | function SelectOnClose () { }
  function CloseOnSelect (line 4696) | function CloseOnSelect () { }
  function Defaults (line 4829) | function Defaults () {
  function stripDiacritics (line 5039) | function stripDiacritics (text) {
  function matcher (line 5048) | function matcher (params, data) {
  function Options (line 5241) | function Options (options, $element) {
  function upperCaseLetter (line 5316) | function upperCaseLetter(_, letter) {
  function syncCssClasses (line 6046) | function syncCssClasses ($dest, $src, adapter) {
  function _containerAdapter (line 6092) | function _containerAdapter (clazz) {
  function ContainerCSS (line 6096) | function ContainerCSS () { }
  function _dropdownAdapter (line 6149) | function _dropdownAdapter (clazz) {
  function DropdownCSS (line 6153) | function DropdownCSS () { }
  function InitSelection (line 6204) | function InitSelection (decorated, $element, options) {
  function InputData (line 6248) | function InputData (decorated, $element, options) {
  function getSelected (line 6266) | function getSelected (data, selectedIds) {
  function oldMatcher (line 6376) | function oldMatcher (matcher) {
  function Query (line 6419) | function Query (decorated, $element, options) {
  function AttachContainer (line 6446) | function AttachContainer (decorated, $element, options) {
  function StopPropagation (line 6465) | function StopPropagation () { }
  function StopPropagation (line 6504) | function StopPropagation () { }
  function handler (line 6632) | function handler(event) {
  function nullLowestDelta (line 6745) | function nullLowestDelta() {
  function shouldAdjustOldDeltas (line 6749) | function shouldAdjustOldDeltas(orgEvent, absDelta) {

FILE: assets/vendor/webui-popover/jquery.webui-popover.js
  function WebuiPopover (line 149) | function WebuiPopover(element, options) {

FILE: class-lifterlms.php
  class LifterLMS (line 28) | final class LifterLMS {
    method __construct (line 75) | private function __construct() {
    method define_constants (line 122) | private function define_constants() {
    method include_template_functions (line 633) | public function include_template_functions() {
    method init (line 650) | public function init() {
    method init_assets (line 674) | private function init_assets() {
    method init_session (line 691) | public function init_session() {
    method plugin_url (line 705) | public function plugin_url() {
    method plugin_path (line 714) | public function plugin_path() {
    method template_path (line 723) | public function template_path() {
    method mailer (line 734) | public function mailer() {
    method achievements (line 745) | public function achievements() {
    method certificates (line 756) | public function certificates() {
    method engagements (line 767) | public function engagements() {
    method block_templates (line 778) | public function block_templates() {
    method events (line 789) | public function events() {
    method grades (line 800) | public function grades() {
    method integrations (line 809) | public function integrations() {
    method notifications (line 820) | public function notifications() {
    method payment_gateways (line 829) | public function payment_gateways() {
    method processors (line 840) | public function processors() {
    method add_action_links (line 852) | public function add_action_links( $links ) {
    method localize (line 891) | public function localize() {

FILE: includes/abstracts/abstract.llms.admin.metabox.php
  class LLMS_Admin_Metabox (line 25) | abstract class LLMS_Admin_Metabox {
    method __construct (line 174) | public function __construct() {
    method add_error (line 206) | public function add_error( $error ) {
    method configure (line 219) | abstract public function configure();
    method get_errors (line 228) | public function get_errors() {
    method get_fields (line 239) | abstract public function get_fields();
    method get_screens (line 249) | private function get_screens() {
    method has_errors (line 263) | public function has_errors() {
    method output (line 274) | public function output() {
    method output_errors (line 302) | public function output_errors() {
    method process_fields (line 331) | private function process_fields() {
    method process_field (line 377) | protected function process_field( $field ) {
    method register (line 417) | public function register() {
    method save (line 467) | protected function save( $post_id ) {
    method save_field (line 516) | protected function save_field( $post_id, $field ) {
    method handler_instructors_mb_store (line 546) | protected function handler_instructors_mb_store( $post_id, $field, $re...
    method save_field_db (line 592) | protected function save_field_db( $post_id, $field_id, $val ) {
    method save_before (line 606) | protected function save_before( $post_id ) {}
    method save_after (line 618) | protected function save_after( $post_id ) {}
    method save_actions (line 632) | public function save_actions( $post_id ) {
    method save_errors (line 658) | public function save_errors() {

FILE: includes/abstracts/abstract.llms.admin.table.php
  class LLMS_Admin_Table (line 20) | abstract class LLMS_Admin_Table extends LLMS_Abstract_Exportable_Admin_T...
    method get_data (line 159) | abstract protected function get_data( $key, $data );
    method get_results (line 169) | abstract public function get_results( $args = array() );
    method set_args (line 178) | abstract public function set_args();
    method set_columns (line 187) | abstract protected function set_columns();
    method __construct (line 196) | public function __construct() {
    method clean_args (line 212) | protected function clean_args( $args = array() ) {
    method filter_get_data (line 238) | protected function filter_get_data( $value, $key, $data, $context = 'd...
    method get_args (line 263) | public function get_args() {
    method get_columns (line 303) | public function get_columns( $context = 'display' ) {
    method get_current_page (line 337) | public function get_current_page() {
    method get_empty_message (line 349) | public function get_empty_message() {
    method get_filter_placeholder (line 372) | public function get_filter_placeholder( $column_id, $column_data ) {
    method get_filter (line 401) | public function get_filter() {
    method get_filterby (line 412) | public function get_filterby() {
    method get_handler (line 423) | public function get_handler() {
    method get_max_pages (line 434) | public function get_max_pages() {
    method get_order (line 445) | public function get_order() {
    method get_orderby (line 456) | public function get_orderby() {
    method get_per_page (line 467) | public function get_per_page() {
    method get_new_order (line 480) | protected function get_new_order( $orderby = '' ) {
    method get_search (line 497) | public function get_search() {
    method get_table_classes (line 508) | protected function get_table_classes() {
    method get_table_filters_html (line 542) | public function get_table_filters_html() {
    method output_table_filters_html (line 555) | public function output_table_filters_html() {
    method get_table_html (line 586) | public function get_table_html() {
    method output_table_html (line 600) | public function output_table_html() {
    method get_table_search_form_html (line 637) | public function get_table_search_form_html() {
    method output_table_search_form_html (line 650) | public function output_table_search_form_html() {
    method get_table_search_form_placeholder (line 667) | public function get_table_search_form_placeholder() {
    method get_table_title_html (line 689) | public function get_table_title_html() {
    method output_table_title_html (line 702) | public function output_table_title_html() {
    method get_tbody_data (line 717) | public function get_tbody_data() {
    method get_tbody_html (line 738) | public function get_tbody_html() {
    method output_tbody_html (line 751) | public function output_tbody_html() {
    method get_tfoot_html (line 775) | public function get_tfoot_html() {
    method output_tfoot_html (line 788) | public function output_tfoot_html() {
    method has_resumable_attempts (line 853) | public function has_resumable_attempts() {
    method get_thead_html (line 870) | public function get_thead_html() {
    method output_thead_html (line 883) | public function output_thead_html() {
    method get_tr_classes (line 917) | protected function get_tr_classes( $row ) {
    method get_tr_html (line 941) | public function get_tr_html( $row ) {
    method output_tr_html (line 955) | public function output_tr_html( $row ) {
    method get_columns_count (line 996) | public function get_columns_count() {
    method get_progress_bar_html (line 1014) | public function get_progress_bar_html( $percentage, $text = '' ) {
    method output_progress_bar_html (line 1033) | public function output_progress_bar_html( $percentage, $text = '' ) {
    method get_post_link (line 1053) | public function get_post_link( $post_id, $text = '' ) {
    method get_title (line 1067) | public function get_title() {
    method get_user_link (line 1089) | public function get_user_link( $user_id, $text = '' ) {
    method is_col_visible (line 1105) | private function is_col_visible( $data, $context = 'display' ) {
    method is_last_page (line 1126) | public function is_last_page() {
    method register_hooks (line 1137) | protected function register_hooks() {}
    method set (line 1148) | public function set( $key, $val ) {
    method set_empty_message (line 1160) | protected function set_empty_message() {
    method set_title (line 1180) | protected function set_title() {

FILE: includes/abstracts/abstract.llms.analytics.widget.php
  class LLMS_Analytics_Widget (line 23) | abstract class LLMS_Analytics_Widget {
    method format_response (line 92) | abstract protected function format_response();
    method set_query (line 93) | abstract protected function set_query();
    method get_chart_data (line 94) | protected function get_chart_data() {
    method __construct (line 105) | public function __construct() {}
    method get_posted_dates (line 115) | protected function get_posted_dates() {
    method get_posted_courses (line 121) | protected function get_posted_courses() {
    method get_posted_memberships (line 127) | protected function get_posted_memberships() {
    method get_posted_posts (line 133) | protected function get_posted_posts() {
    method get_posted_students (line 137) | protected function get_posted_students() {
    method get_prepared_query (line 142) | protected function get_prepared_query() {
    method get_query (line 146) | protected function get_query() {
    method get_query_vars (line 150) | protected function get_query_vars() {
    method get_results (line 154) | protected function get_results() {
    method format_date (line 158) | protected function format_date( $date, $type ) {
    method is_error (line 185) | protected function is_error() {
    method set_order_data_query (line 190) | protected function set_order_data_query( $args = array() ) {
    method query (line 304) | protected function query() {
    method _can_be_processed (line 346) | protected function _can_be_processed() { // phpcs:ignore -- PSR2.Metho...
    method can_be_processed (line 366) | public function can_be_processed() {
    method output (line 397) | public function output() {

FILE: includes/abstracts/abstract.llms.database.query.php
  class LLMS_Database_Query (line 20) | abstract class LLMS_Database_Query extends LLMS_Abstract_Query {
    method default_arguments (line 48) | protected function default_arguments() {
    method escape_and_quote_string (line 70) | public function escape_and_quote_string( $input ) {
    method get_default_args (line 86) | protected function get_default_args() {
    method get_filter (line 116) | protected function get_filter( $filter ) {
    method get_skip (line 127) | protected function get_skip() {
    method perform_query (line 138) | protected function perform_query() {
    method set_found_results (line 153) | protected function set_found_results() {
    method found_results (line 177) | protected function found_results() {
    method sql_select_columns (line 197) | protected function sql_select_columns( $select_columns = '*' ) {
    method sql_limit (line 225) | protected function sql_limit() {
    method sql_orderby (line 257) | protected function sql_orderby() {
    method query (line 309) | public function query() {
    method legacy_public_props (line 358) | private function legacy_public_props() {
    method public_prop_deprecation (line 378) | private function public_prop_deprecation( $prop ) {
    method __get (line 398) | public function __get( $key ) {
    method __set (line 422) | public function __set( $key, $val ) {
    method __call (line 444) | public function __call( $name, $args ) {
    method prepare_query (line 467) | protected function prepare_query() {

FILE: includes/abstracts/abstract.llms.payment.gateway.php
  class LLMS_Payment_Gateway (line 20) | abstract class LLMS_Payment_Gateway extends LLMS_Abstract_Options_Data {
    method add_secure_string (line 164) | public function add_secure_string( $string ) {
    method complete_transaction (line 180) | public function complete_transaction( $order, $deprecated = null ) {
    method complete_transaction_ajax (line 214) | public function complete_transaction_ajax( $order, $data = array() ) {
    method is_external_payment_entry (line 237) | public function is_external_payment_entry() {
    method confirm_pending_order (line 262) | public function confirm_pending_order( $order ) {}
    method get_admin_description (line 271) | public function get_admin_description() {
    method get_admin_title (line 291) | public function get_admin_title() {
    method get_admin_order_fields (line 311) | public function get_admin_order_fields() {
    method get_admin_settings_fields (line 350) | public function get_admin_settings_fields() {
    method get_api_mode (line 432) | public function get_api_mode() {
    method get_complete_transaction_redirect_url (line 448) | protected function get_complete_transaction_redirect_url( $order ) {
    method get_customer_url (line 500) | public function get_customer_url( $customer_id, $api_mode = 'live' ) {
    method get_description (line 511) | public function get_description() {
    method get_display_order (line 522) | public function get_display_order() {
    method get_enabled (line 533) | public function get_enabled() {
    method get_fields (line 546) | public function get_fields() {
    method get_icon (line 565) | public function get_icon() {
    method get_id (line 584) | public function get_id() {
    method get_item_link (line 600) | public function get_item_link( $item_key, $item_value, $api_mode = 'li...
    method get_logging_enabled (line 636) | public function get_logging_enabled() {
    method get_secure_strings (line 665) | public function get_secure_strings( $strings, $handle ) {
    method get_source_url (line 686) | public function get_source_url( $source_id, $api_mode = 'live' ) {
    method get_subscription_url (line 701) | public function get_subscription_url( $subscription_id, $api_mode = 'l...
    method get_supported_features (line 713) | public function get_supported_features() {
    method get_test_mode_description (line 737) | public function get_test_mode_description() {
    method get_test_mode_enabled (line 748) | public function get_test_mode_enabled() {
    method get_test_mode_title (line 759) | public function get_test_mode_title() {
    method get_title (line 770) | public function get_title() {
    method get_transaction_url (line 786) | public function get_transaction_url( $transaction_id, $api_mode = 'liv...
    method handle_payment_source_switch (line 806) | public function handle_payment_source_switch( $order, $form_data = arr...
    method handle_pending_order (line 832) | abstract public function handle_pending_order( $order, $plan, $person,...
    method handle_recurring_transaction (line 844) | public function handle_recurring_transaction( $order ) {}
    method is_default_gateway (line 856) | public function is_default_gateway() {
    method is_enabled (line 867) | public function is_enabled() {
    method is_test_mode_enabled (line 880) | public function is_test_mode_enabled() {
    method log (line 892) | public function log() {
    method get_option (line 924) | public function get_option( $key, $secure_key = false ) {
    method get_option_default_value (line 962) | public function get_option_default_value( $default_value, $full_option...
    method get_option_prefix (line 976) | protected function get_option_prefix() {
    method process_refund (line 994) | public function process_refund( $transaction, $amount = 0, $note = '' ...
    method retrieve_secure_strings (line 1007) | public function retrieve_secure_strings() {
    method supports (line 1050) | public function supports( $feature, $order = null ) {
    method can_process_access_plan (line 1072) | public function can_process_access_plan( $plan, $order = null ) {

FILE: includes/abstracts/abstract.llms.post.model.php
  class LLMS_Post_Model (line 51) | abstract class LLMS_Post_Model implements JsonSerializable {
    method __construct (line 130) | public function __construct( $model, $args = array() ) {
    method __get (line 176) | public function __get( $key ) {
    method __isset (line 188) | public function __isset( $key ) {
    method __set (line 201) | public function __set( $key, $val ) {
    method add_properties (line 212) | protected function add_properties( $props = array() ) {
    method allowed_post_tags_set (line 224) | protected function allowed_post_tags_set() {
    method allowed_post_tags_unset (line 243) | protected function allowed_post_tags_unset() {
    method translate (line 260) | public function translate( $key ) {
    method _e (line 284) | public function _e( $key ) { // phpcs:ignore -- This is to mimic local...
    method after_create (line 297) | protected function after_create() {}
    method create (line 311) | private function create( $title = '' ) {
    method clone_post (line 344) | public function clone_post() {
    method export (line 378) | public function export() {
    method ___get (line 432) | private function ___get( $key, $raw = false ) {
    method get (line 537) | public function get( $key, $raw = false ) {
    method get_array (line 556) | public function get_array( $key ) {
    method get_date (line 575) | public function get_date( $key, $format = null ) {
    method get_date_format (line 608) | protected function get_date_format() {
    method get_default_value (line 634) | public function get_default_value( $key ) {
    method get_image (line 653) | public function get_image( $size = 'full', $key = '' ) {
    method get_post_type_data (line 675) | public function get_post_type_data() {
    method get_post_type_label (line 688) | public function get_post_type_label( $label = 'singular_name' ) {
    method get_price (line 708) | public function get_price( $key, $price_args = array(), $format = 'htm...
    method get_property_defaults (line 772) | public function get_property_defaults() {
    method get_creation_args (line 798) | protected function get_creation_args( $args = null ) {
    method get_embed (line 852) | protected function get_embed( $type = 'video', $prop = '' ) {
    method get_property_type (line 894) | protected function get_property_type( $key ) {
    method get_post_properties (line 919) | protected function get_post_properties() {
    method get_properties (line 960) | public function get_properties() {
    method get_to_array_properties (line 983) | protected function get_to_array_properties() {
    method get_to_array_excluded_properties (line 1039) | protected function get_to_array_excluded_properties() {
    method get_status_name (line 1050) | public function get_status_name() {
    method get_terms (line 1076) | public function get_terms( $tax, $single = false ) {
    method get_unsettable_properties (line 1098) | protected function get_unsettable_properties() {
    method is_cloneable (line 1127) | public function is_cloneable() {
    method is_exportable (line 1138) | public function is_exportable() {
    method jsonSerialize (line 1155) | #[ReturnTypeWillChange]
    method scrub (line 1180) | protected function scrub( $key, $val ) {
    method scrub_field (line 1224) | protected function scrub_field( $val, $type ) {
    method set (line 1294) | public function set( $key_or_array, $val = '', $allow_same_meta_value ...
    method set_bulk (line 1323) | public function set_bulk( $model_array, $wp_error = false, $allow_same...
    method parse_properties_to_set (line 1362) | private function parse_properties_to_set( $model_array ) {
    method update_post_properties (line 1455) | private function update_post_properties( $post_properties ) {
    method update_meta_properties (line 1489) | private function update_meta_properties( $post_meta_properties, $allow...
    method is_meta_value_same_as_stored_value (line 1539) | private function is_meta_value_same_as_stored_value( $key, $stored_val...
    method set_terms (line 1573) | public function set_terms( $terms, $tax, $append = false ) {
    method toArray (line 1599) | public function toArray() {
    method get_provider_support (line 1701) | public function get_provider_support( $url ) {
    method toArrayAfter (line 1730) | protected function toArrayAfter( $arr ) {
    method to_array_extra (line 1750) | protected function to_array_extra( $arr ) {
    method to_array_extra_blocks (line 1773) | protected function to_array_extra_blocks( $content ) {
    method to_array_extra_images (line 1805) | protected function to_array_extra_images( $content ) {
    method toArrayCustom (line 1840) | protected function toArrayCustom( $arr ) {

FILE: includes/abstracts/abstract.llms.shortcode.course.element.php
  class LLMS_Shortcode_Course_Element (line 18) | abstract class LLMS_Shortcode_Course_Element extends LLMS_Shortcode {
    method template_function (line 27) | abstract protected function template_function();
    method get_default_attributes (line 37) | protected function get_default_attributes() {
    method get_output (line 53) | protected function get_output() {

FILE: includes/abstracts/abstract.llms.shortcode.php
  class LLMS_Shortcode (line 18) | abstract class LLMS_Shortcode {
    method get_output (line 37) | abstract protected function get_output();
    method get_default_attributes (line 47) | protected function get_default_attributes() {
    method get_default_content (line 58) | protected function get_default_content() {
    method instance (line 79) | public static function instance() {
    method __construct (line 96) | private function __construct() {
    method enqueue_script (line 109) | protected function enqueue_script( $handle ) {
    method get_attributes (line 126) | public function get_attributes() {
    method get_attribute (line 139) | public function get_attribute( $key, $default = '' ) {
    method get_content (line 154) | public function get_content() {
    method get_filter (line 167) | protected function get_filter( $filter ) {
    method output (line 187) | public function output( $atts = array(), $content = '' ) {
    method set_attributes (line 210) | protected function set_attributes( $atts = array() ) {

FILE: includes/abstracts/llms-abstract-admin-tool.php
  class LLMS_Abstract_Admin_Tool (line 18) | abstract class LLMS_Abstract_Admin_Tool {
    method handle (line 47) | abstract protected function handle();
    method get_description (line 58) | abstract protected function get_description();
    method get_label (line 69) | abstract protected function get_label();
    method get_text (line 78) | abstract protected function get_text();
    method __construct (line 87) | public function __construct() {
    method maybe_handle (line 103) | public function maybe_handle( $tool_id ) {
    method register (line 151) | public function register( $tools ) {
    method should_load (line 177) | protected function should_load() {

FILE: includes/abstracts/llms-abstract-admin-wizard.php
  class LLMS_Abstract_Admin_Wizard (line 18) | abstract class LLMS_Abstract_Admin_Wizard {
    method add_hooks (line 66) | protected function add_hooks(): void {
    method hide_admin_header (line 99) | public function hide_admin_header( bool $show, WP_Screen $screen, stri...
    method admin_menu (line 114) | public function admin_menu() {
    method enqueue (line 147) | public function enqueue(): bool {
    method get_completed_url (line 165) | abstract protected function get_completed_url( array $course_ids ): st...
    method get_current_step (line 174) | public function get_current_step(): string {
    method get_next_step (line 190) | public function get_next_step( string $step = null ) {
    method get_prev_step (line 211) | public function get_prev_step( string $step = null ) {
    method get_save_text (line 231) | private function get_save_text( string $step ): string {
    method get_skip_text (line 260) | private function get_skip_text( string $step ): string {
    method get_step_url (line 290) | protected function get_step_url( string $step ): string {
    method get_steps (line 307) | public function get_steps(): array {
    method output (line 330) | public function output(): void {
    method save (line 376) | public function save(): ?WP_Error {
    method get_transient (line 416) | protected function get_transient(): array {

FILE: includes/abstracts/llms-abstract-controller-user-engagements.php
  class LLMS_Abstract_Controller_User_Engagements (line 18) | abstract class LLMS_Abstract_Controller_User_Engagements {
    method __construct (line 83) | public function __construct() {
    method delete (line 98) | protected function delete( $post_id ) {
    method get_text (line 122) | protected function get_text( $text_type, $variables = array() ) {
    method maybe_handle_awarded_engagement_sync_actions (line 139) | public function maybe_handle_awarded_engagement_sync_actions() {
    method sync_awarded_engagement (line 207) | private function sync_awarded_engagement( $engagement_id ) {
    method sync_awarded_engagements (line 244) | private function sync_awarded_engagements( $user_engagement_template_i...

FILE: includes/abstracts/llms-abstract-email-provider.php
  class LLMS_Abstract_Email_Provider (line 19) | abstract class LLMS_Abstract_Email_Provider {
    method do_remote_install_success (line 45) | abstract protected function do_remote_install_success();
    method get_connect_setting (line 54) | abstract protected function get_connect_setting();
    method get_description (line 63) | abstract protected function get_description();
    method get_title (line 72) | abstract protected function get_title();
    method is_connected (line 81) | abstract protected function is_connected();
    method is_installed (line 90) | abstract protected function is_installed();
    method __construct (line 99) | public function __construct() {
    method init (line 131) | public function init() {
    method activate_already_installed_plugin (line 168) | protected function activate_already_installed_plugin() {
    method add_settings (line 195) | public function add_settings( $settings ) {
    method ajax_callback_remote_install (line 226) | public function ajax_callback_remote_install() {
    method ajax_callback_remote_install_verify (line 240) | public function ajax_callback_remote_install_verify() {
    method can_remote_install (line 254) | protected function can_remote_install() {
    method disable_other_providers (line 281) | protected function disable_other_providers() {
    method do_remote_install (line 296) | protected function do_remote_install() {
    method do_remote_install_verify (line 321) | protected function do_remote_install_verify() {
    method install (line 348) | protected function install() {
    method install_plugin (line 368) | protected function install_plugin() {
    method should_output_inline (line 408) | protected function should_output_inline() {

FILE: includes/abstracts/llms-abstract-generator-posts.php
  class LLMS_Abstract_Generator_Posts (line 22) | abstract class LLMS_Abstract_Generator_Posts {
    method __construct (line 99) | public function __construct() {
    method add_custom_values (line 117) | public function add_custom_values( $post_id, $raw ) {
    method add_custom_value (line 145) | protected function add_custom_value( $post_id, $key, $val ) {
    method create_post (line 170) | protected function create_post( $type, $raw = array(), $author_id = nu...
    method create_reusable_block (line 249) | protected function create_reusable_block( $block_id, $block ) {
    method create_user (line 278) | protected function create_user( $raw ) {
    method format_date (line 348) | public function format_date( $raw_date = null ) {
    method get_author_id (line 375) | protected function get_author_id( $raw ) {
    method get_author_id_from_raw (line 456) | public function get_author_id_from_raw( $raw, $fallback_author_id = nu...
    method get_default_post_status (line 480) | public function get_default_post_status() {
    method get_term_id (line 508) | protected function get_term_id( $term_name, $tax ) {
    method handle_reusable_blocks (line 546) | protected function handle_reusable_blocks( $post, $raw ) {
    method insert_resuable_block (line 594) | protected function insert_resuable_block( $block_id, $block ) {
    method is_image_sideloading_enabled (line 631) | public function is_image_sideloading_enabled() {
    method is_reusable_block_importing_enabled (line 651) | public function is_reusable_block_importing_enabled() {
    method load_dependencies (line 671) | protected function load_dependencies() {
    method set_featured_image (line 690) | protected function set_featured_image( $url_or_raw, $post_id ) {
    method set_default_post_status (line 719) | public function set_default_post_status( $status ) {
    method set_metadata (line 734) | protected function set_metadata( $post, $raw ) {
    method sideload_image (line 755) | protected function sideload_image( $post_id, $url, $return = 'src' ) {
    method sideload_images (line 788) | protected function sideload_images( $post, $raw ) {
    method store_temp_id (line 854) | protected function store_temp_id( $raw, $obj ) {

FILE: includes/abstracts/llms-abstract-meta-box-user-engagement-sync.php
  class LLMS_Abstract_Meta_Box_User_Engagement_Sync (line 18) | abstract class LLMS_Abstract_Meta_Box_User_Engagement_Sync extends LLMS_...
    method configure (line 148) | public function configure() {
    method get_fields (line 182) | public function get_fields() {
    method get_sync_action_texts (line 195) | private function get_sync_action_texts() {
    method get_text (line 239) | protected function get_text( $text_type, $variables = array() ) {
    method output (line 255) | public function output() {
    method sync_action (line 274) | private function sync_action() {

FILE: includes/abstracts/llms-abstract-posts-query.php
  class LLMS_Abstract_Posts_Query (line 30) | abstract class LLMS_Abstract_Posts_Query extends LLMS_Abstract_Query {
    method count_results (line 72) | protected function count_results() {
    method default_arguments (line 87) | protected function default_arguments() {
    method found_results (line 111) | protected function found_results() {
    method get_arg_map (line 122) | protected function get_arg_map() {
    method get_wp_query (line 142) | public function get_wp_query() {
    method perform_query (line 153) | protected function perform_query() {
    method prepare_query (line 169) | protected function prepare_query() {
    method set (line 195) | public function set( $key, $val ) {
    method sanitize_post_types (line 216) | protected function sanitize_post_types( $val ) {

FILE: includes/abstracts/llms-abstract-processor-user-engagement-sync.php
  class LLMS_Abstract_Processor_User_Engagement_Sync (line 18) | abstract class LLMS_Abstract_Processor_User_Engagement_Sync extends LLMS...
    method clear_notices (line 66) | private function clear_notices( $engagement_template_id ) {
    method dispatch_sync (line 88) | public function dispatch_sync( $engagement_template_id ) {
    method get_text (line 153) | protected function get_text( $text_type, $variables = array() ) {
    method init (line 165) | protected function init() {
    method process_completed (line 189) | private function process_completed( $args ) {
    method schedule_sync (line 226) | public function schedule_sync( $engagement_template_id ) {
    method sync_awarded_engagements (line 293) | private function sync_awarded_engagements( $engagements, $template_id ) {
    method task (line 321) | public function task( $args ) {

FILE: includes/abstracts/llms-abstract-query.php
  class LLMS_Abstract_Query (line 27) | abstract class LLMS_Abstract_Query {
    method __construct (line 124) | public function __construct( $args = array() ) {
    method count_results (line 141) | protected function count_results() {
    method default_arguments (line 162) | protected function default_arguments() {
    method found_results (line 182) | abstract protected function found_results();
    method get (line 194) | public function get( $key, $default = '' ) {
    method get_arguments (line 207) | public function get_arguments() {
    method get_arguments_default (line 220) | public function get_arguments_default() {
    method get_arguments_original (line 233) | public function get_arguments_original() {
    method get_query (line 246) | public function get_query() {
    method get_allowed_sort_fields (line 257) | protected function get_allowed_sort_fields() {
    method get_default_args (line 287) | protected function get_default_args() {
    method get_found_results (line 316) | public function get_found_results() {
    method get_max_pages (line 332) | public function get_max_pages() {
    method get_number_results (line 345) | public function get_number_results() {
    method get_results (line 358) | public function get_results() {
    method has_results (line 384) | public function has_results() {
    method is_first_page (line 397) | public function is_first_page() {
    method is_last_page (line 410) | public function is_last_page() {
    method parse_args (line 421) | abstract protected function parse_args();
    method perform_query (line 430) | abstract protected function perform_query();
    method prepare_query (line 441) | abstract protected function prepare_query();
    method query (line 452) | public function query() {
    method sanitize_id_array (line 484) | protected function sanitize_id_array( $ids = array() ) {
    method sanitize_sort (line 509) | protected function sanitize_sort( $sort ) {
    method set (line 536) | public function set( $key, $val ) {
    method setup_args (line 550) | protected function setup_args() {
    method get_count_only_result (line 580) | public function get_count_only_result() {

FILE: includes/abstracts/llms-abstract-session-data.php
  class LLMS_Abstract_Session_Data (line 18) | abstract class LLMS_Abstract_Session_Data {
    method generate_id (line 57) | protected function generate_id() {
    method get_id (line 79) | public function get_id() {
    method get (line 98) | public function get( $key, $default = false ) {
    method set (line 115) | public function set( $key, $value ) {
    method __get (line 140) | public function __get( $key ) {
    method __set (line 154) | public function __set( $key, $value ) {
    method __isset (line 167) | public function __isset( $key ) {
    method __unset (line 180) | public function __unset( $key ) {

FILE: includes/abstracts/llms-abstract-session-database-handler.php
  class LLMS_Abstract_Session_Database_Handler (line 18) | abstract class LLMS_Abstract_Session_Database_Handler extends LLMS_Abstr...
    method clean (line 40) | public function clean( $expired_only = true ) {
    method delete (line 63) | public function delete( $id ) {
    method get_cache_key (line 85) | protected function get_cache_key( $key ) {
    method save (line 97) | public function save( $expires ) {
    method read (line 131) | public function read( $key, $default = array() ) {

FILE: includes/abstracts/llms-abstract-user-engagement.php
  class LLMS_Abstract_User_Engagement (line 18) | abstract class LLMS_Abstract_User_Engagement extends LLMS_Post_Model {
    method __construct (line 31) | public function __construct( $model, $args = array() ) {
    method after_create (line 44) | protected function after_create() {
    method delete (line 57) | public function delete() {
    method get_earned_date (line 108) | public function get_earned_date( $format = null ) {
    method get_related_post_id (line 126) | public function get_related_post_id() {
    method get_user_id (line 143) | public function get_user_id() {
    method get_user_postmeta (line 158) | public function get_user_postmeta() {
    method get_user_post_meta_key (line 178) | protected function get_user_post_meta_key() {
    method is_awarded (line 190) | public function is_awarded() {
    method merge_content (line 209) | public function merge_content( $content = null, $load_reusable_blocks ...
    method sync (line 234) | public function sync( $context = 'update' ) {
    method sync_meta (line 281) | protected function sync_meta( $template ) {

FILE: includes/abstracts/llms.abstract.api.handler.php
  class LLMS_Abstract_API_Handler (line 19) | abstract class LLMS_Abstract_API_Handler {
    method __construct (line 64) | public function __construct( $resource, $data, $method = null ) {
    method call (line 83) | private function call( $resource, $data, $method = null ) {
    method get_error_message (line 141) | public function get_error_message() {
    method get_error_object (line 154) | public function get_error_object() {
    method get_error_type (line 167) | public function get_error_type() {
    method get_result (line 180) | public function get_result() {
    method is_error (line 193) | public function is_error() {
    method parse_response (line 207) | abstract protected function parse_response( $response );
    method set_error (line 220) | protected function set_error( $message, $type, $obj ) {
    method set_result (line 236) | protected function set_result( $result ) {
    method set_request_body (line 250) | abstract protected function set_request_body( $data, $method, $resourc...
    method set_request_headers (line 262) | protected function set_request_headers( $headers, $resource, $method ) {
    method set_request_url (line 275) | abstract protected function set_request_url( $resource, $method );
    method set_user_agent (line 288) | protected function set_user_agent( $user_agent, $resource, $method ) {

FILE: includes/abstracts/llms.abstract.database.store.php
  class LLMS_Abstract_Database_Store (line 24) | abstract class LLMS_Abstract_Database_Store {
    method __construct (line 109) | public function __construct() {
    method __get (line 133) | public function __get( $key ) {
    method exists (line 145) | public function exists() {
    method get (line 166) | public function get( $key, $cache = true ) {
    method __set (line 189) | public function __set( $key, $val ) {
    method set (line 204) | public function set( $key, $val, $save = false ) {
    method setup (line 231) | public function setup( $data ) {
    method create (line 251) | private function create() {
    method delete (line 292) | public function delete() {
    method read (line 332) | private function read( $keys ) {
    method update (line 357) | private function update( $data ) {
    method hydrate (line 390) | protected function hydrate() {
    method save (line 413) | public function save() {
    method get_column_format (line 435) | private function get_column_format( $key ) {
    method get_primary_key (line 451) | protected function get_primary_key() {
    method get_id (line 463) | public function get_id() {
    method get_table (line 474) | private function get_table() {
    method to_array (line 490) | public function to_array() {

FILE: includes/abstracts/llms.abstract.exportable.admin.table.php
  class LLMS_Abstract_Exportable_Admin_Table (line 21) | abstract class LLMS_Abstract_Exportable_Admin_Table {
    method generate_export_file (line 63) | public function generate_export_file( $args = array(), $filename = nul...
    method get_export (line 136) | public function get_export( $args = array() ) {
    method get_export_data (line 166) | public function get_export_data( $key, $data ) {
    method get_export_file_url (line 180) | protected function get_export_file_url( $file_path ) {
    method get_export_header (line 198) | public function get_export_header() {
    method get_export_file_name (line 237) | public function get_export_file_name( $args = array() ) {
    method get_export_lock_key (line 277) | public function get_export_lock_key() {
    method get_export_title (line 290) | public function get_export_title( $args = array() ) {
    method get_title (line 303) | public function get_title() {
    method is_export_locked (line 325) | public function is_export_locked() {

FILE: includes/abstracts/llms.abstract.integration.php
  class LLMS_Abstract_Integration (line 18) | abstract class LLMS_Abstract_Integration extends LLMS_Abstract_Options_D...
    method __construct (line 87) | public function __construct() {
    method configure (line 119) | abstract protected function configure();
    method add_settings (line 131) | public function add_settings( $settings ) {
    method get_integration_settings (line 145) | protected function get_integration_settings() {
    method get_priority (line 156) | public function get_priority() {
    method get_settings (line 169) | protected function get_settings() {
    method get_option_prefix (line 224) | protected function get_option_prefix() {
    method get_option_default_value (line 243) | public function get_option_default_value( $default_value, $full_option...
    method is_available (line 270) | public function is_available() {
    method is_enabled (line 282) | public function is_enabled() {
    method is_installed (line 296) | public function is_installed() {
    method plugin_action_links (line 312) | public function plugin_action_links( $links, $file, $data, $context ) {

FILE: includes/abstracts/llms.abstract.notification.controller.php
  class LLMS_Abstract_Notification_Controller (line 19) | abstract class LLMS_Abstract_Notification_Controller extends LLMS_Abstra...
    method get_subscriber (line 118) | abstract protected function get_subscriber( $subscriber );
    method get_title (line 129) | abstract public function get_title();
    method set_subscriber_options (line 139) | abstract protected function set_subscriber_options( $type );
    method instance (line 156) | public static function instance() {
    method __construct (line 174) | private function __construct() {
    method add_actions (line 186) | protected function add_actions() {
    method add_custom_subscriptions (line 200) | private function add_custom_subscriptions( $type ) {
    method add_subscriptions (line 221) | private function add_subscriptions( $filter_types = null ) {
    method get_mock_view (line 258) | public function get_mock_view( $type = 'basic', $subscriber = null, $u...
    method get_option_prefix (line 279) | protected function get_option_prefix() {
    method get_subscriber_options (line 291) | public function get_subscriber_options( $type ) {
    method get_subscribers_settings (line 312) | public function get_subscribers_settings( $type ) {
    method get_subscriber_option_array (line 327) | public function get_subscriber_option_array( $id, $enabled = 'yes' ) {
    method get_subscriber_subscriptions (line 364) | public function get_subscriber_subscriptions( $subscriber ) {
    method get_subscriptions (line 376) | public function get_subscriptions() {
    method get_supported_types (line 387) | public function get_supported_types() {
    method get_additional_options (line 408) | public function get_additional_options( $type ) {
    method get_test_settings (line 429) | public function get_test_settings( $type ) {
    method has_subscriber_received (line 444) | public function has_subscriber_received( $type, $subscriber ) {
    method is_testable (line 469) | public function is_testable( $type ) {
    method send (line 491) | public function send( $force = false, $filter_types = null ) {
    method send_one (line 531) | protected function send_one( $type, $subscriber, $force = false ) {
    method send_test (line 583) | public function send_test( $type, $data = array() ) {
    method set_supported_types (line 597) | protected function set_supported_types() {
    method set_additional_options (line 613) | protected function set_additional_options( $type ) {
    method subscribe (line 627) | public function subscribe( $subscriber, $type ) {
    method supports (line 652) | public function supports( $type ) {
    method unset_subscriptions (line 663) | public function unset_subscriptions() {

FILE: includes/abstracts/llms.abstract.notification.processor.php
  class LLMS_Abstract_Notification_Processor (line 19) | abstract class LLMS_Abstract_Notification_Processor extends WP_Backgroun...
    method __construct (line 34) | public function __construct() {
    method complete (line 53) | protected function complete() {
    method dispatch (line 69) | public function dispatch() {
    method handle_cron_healthcheck (line 107) | public function handle_cron_healthcheck() {
    method is_processing (line 127) | public function is_processing() {
    method log (line 139) | public function log( $data ) {

FILE: includes/abstracts/llms.abstract.notification.view.php
  class LLMS_Abstract_Notification_View (line 23) | abstract class LLMS_Abstract_Notification_View extends LLMS_Abstract_Opt...
    method set_merge_data (line 105) | abstract protected function set_merge_data( $code );
    method set_body (line 114) | abstract protected function set_body();
    method set_footer (line 123) | abstract protected function set_footer();
    method set_icon (line 132) | abstract protected function set_icon();
    method set_merge_codes (line 141) | abstract protected function set_merge_codes();
    method set_subject (line 150) | abstract protected function set_subject();
    method set_title (line 161) | abstract protected function set_title();
    method __construct (line 175) | public function __construct( $notification ) {
    method __destruct (line 204) | public function __destruct() {
    method set_shortcode_user (line 216) | public function set_shortcode_user( $uid ) {
    method get_object (line 227) | protected function get_object() {
    method get_basic_html (line 238) | private function get_basic_html() {
    method get_body (line 300) | public function get_body( $merge = true ) {
    method get_date (line 317) | public function get_date( $date = 'created', $format = null ) {
    method get_date_display (line 337) | public function get_date_display( $max_days = 5 ) {
    method get_date_relative (line 360) | public function get_date_relative( $date = 'created' ) {
    method get_email_html (line 372) | private function get_email_html() {
    method get_filter (line 384) | protected function get_filter( $hook ) {
    method get_field_options (line 396) | public function get_field_options( $type ) {
    method get_footer (line 459) | public function get_footer() {
    method get_html (line 471) | public function get_html() {
    method get_icon (line 503) | public function get_icon() {
    method get_icon_default (line 518) | public function get_icon_default( $type ) {
    method get_icon_src (line 534) | public function get_icon_src() {
    method get_merge_codes (line 557) | public function get_merge_codes() {
    method get_merge_code_defaults (line 575) | protected function get_merge_code_defaults() {
    method get_merged_string (line 602) | private function get_merged_string( $string ) {
    method get_used_merge_codes (line 639) | private function get_used_merge_codes( $string ) {
    method get_notification (line 659) | public function get_notification() {
    method get_option_prefix (line 672) | protected function get_option_prefix() {
    method get_subject (line 683) | public function get_subject( $merge = true ) {
    method get_supported_fields (line 698) | public function get_supported_fields() {
    method get_title (line 709) | public function get_title( $merge = true ) {
    method has_field_support (line 726) | protected function has_field_support( $type, $field ) {
    method is_for_self (line 745) | protected function is_for_self() {
    method sentence_case (line 760) | private function sentence_case( $string ) {
    method set_merge_data_default (line 779) | protected function set_merge_data_default( $code ) {
    method set_supported_fields (line 804) | protected function set_supported_fields() {

FILE: includes/abstracts/llms.abstract.notification.view.quiz.completion.php
  class LLMS_Abstract_Notification_View_Quiz_Completion (line 19) | abstract class LLMS_Abstract_Notification_View_Quiz_Completion extends L...
    method set_body_email (line 46) | protected function set_body_email() {
    method set_footer (line 78) | protected function set_footer() {
    method set_merge_codes (line 89) | protected function set_merge_codes() {
    method set_merge_data (line 113) | protected function set_merge_data( $code ) {

FILE: includes/abstracts/llms.abstract.options.data.php
  class LLMS_Abstract_Options_Data (line 18) | abstract class LLMS_Abstract_Options_Data {
    method get_option (line 49) | public function get_option( $name, $default = false ) {
    method get_option_deprecated (line 86) | private function get_option_deprecated( $name, $default = '' ) {
    method get_option_default_value (line 110) | public function get_option_default_value( $default_value, $full_option...
    method get_option_prefix (line 121) | protected function get_option_prefix() {
    method get_option_name (line 135) | public function get_option_name( $name ) {
    method set_option (line 148) | public function set_option( $name, $value ) {

FILE: includes/abstracts/llms.abstract.post.data.php
  class LLMS_Abstract_Post_Data (line 18) | abstract class LLMS_Abstract_Post_Data {
    method __construct (line 49) | public function __construct( $post_id ) {
    method get_post (line 63) | public function get_post() {
    method get_post_id (line 74) | public function get_post_id() {
    method strtotime (line 86) | protected function strtotime( $date ) {
    method get_date (line 102) | protected function get_date( $period, $date ) {
    method parse_period (line 117) | public function parse_period() {
    method set_period (line 134) | public function set_period( $period = 'today' ) {
    method recent_events (line 241) | public function recent_events( $args = array() ) {

FILE: includes/abstracts/llms.abstract.privacy.php
  class LLMS_Abstract_Privacy (line 20) | abstract class LLMS_Abstract_Privacy {
    method __construct (line 51) | public function __construct( $name = '' ) {
    method add_hooks (line 64) | protected function add_hooks() {
    method add_privacy_message (line 79) | public function add_privacy_message() {
    method get_privacy_message (line 98) | public function get_privacy_message() {
    method get_student_by_email (line 111) | protected static function get_student_by_email( $email ) {
    method register_erasers (line 131) | public function register_erasers( $erasers = array() ) {
    method register_exporters (line 149) | public function register_exporters( $exporters = array() ) {
    method add_eraser (line 167) | public function add_eraser( $id, $name, $callback ) {
    method add_exporter (line 186) | public function add_exporter( $id, $name, $callback ) {

FILE: includes/abstracts/llms.abstract.processor.php
  class LLMS_Abstract_Processor (line 18) | abstract class LLMS_Abstract_Processor extends WP_Background_Process {
    method init (line 44) | abstract protected function init();
    method __construct (line 61) | public function __construct() {
    method add_actions (line 82) | public function add_actions() {
    method disable (line 110) | public function disable() {
    method dispatch (line 139) | public function dispatch() {
    method get_actions (line 162) | private function get_actions() {
    method get_data (line 178) | public function get_data( $key = null, $default = '' ) {
    method get_edit_post_link (line 215) | protected function get_edit_post_link( $id = 0, $context = 'display' ) {
    method log (line 258) | protected function log( $data ) {
    method save_data (line 274) | private function save_data( $data ) {
    method set_data (line 298) | public function set_data( $key, $value ) {
    method unset_data (line 316) | public function unset_data( $key ) {

FILE: includes/abstracts/llms.abstract.user.data.php
  class LLMS_Abstract_User_Data (line 21) | abstract class LLMS_Abstract_User_Data {
    method __construct (line 58) | public function __construct( $user = null, $autoload = true ) {
    method __get (line 80) | public function __get( $key ) {
    method cache_get (line 127) | protected function cache_get( $key ) {
    method cache_delete (line 139) | protected function cache_delete( $key ) {
    method cache_set (line 152) | protected function cache_set( $key, $val ) {
    method exists (line 163) | public function exists() {
    method get (line 175) | public function get( $key ) {
    method get_cache_group (line 186) | protected function get_cache_group() {
    method get_id (line 198) | public function get_id() {
    method get_student (line 209) | protected function get_student() {
    method get_user (line 220) | public function get_user() {
    method get_user_id (line 232) | protected function get_user_id( $user ) {
    method set (line 258) | public function set( $key, $value, $prefix = true ) {

FILE: includes/achievements/class.llms.achievement.user.php
  class LLMS_Achievement_User (line 24) | class LLMS_Achievement_User extends LLMS_Achievement {
    method __call (line 108) | public function __call( $name, $args ) {
    method __construct (line 118) | public function __construct() {
    method has_user_earned (line 132) | private function has_user_earned() {
    method init (line 172) | private function init( $id, $person_id, $lesson_id ) {
    method trigger (line 205) | private function trigger( $user_id, $id, $lesson_id ) {
    method get_content_html (line 238) | private function get_content_html() {

FILE: includes/admin/class-llms-admin-events-promo.php
  class LLMS_Admin_Events_Promo (line 22) | class LLMS_Admin_Events_Promo {
    method __construct (line 29) | public function __construct() {
    method add_course_promo_tab (line 48) | public function add_course_promo_tab( $tabs ) {
    method add_membership_promo_tab (line 71) | public function add_membership_promo_tab( $tabs ) {
    method add_lesson_promo_tab (line 94) | public function add_lesson_promo_tab( $tabs ) {
    method get_promo_html (line 116) | private function get_promo_html() {

FILE: includes/admin/class-llms-admin-export-download.php
  class LLMS_Admin_Export_Download (line 18) | class LLMS_Admin_Export_Download {
    method __construct (line 26) | public function __construct() {
    method maybe_serve_export (line 40) | public function maybe_serve_export() {

FILE: includes/admin/class-llms-admin-header.php
  class LLMS_Admin_Header (line 18) | class LLMS_Admin_Header {
    method __construct (line 27) | public function __construct() {
    method admin_header (line 41) | public function admin_header() {

FILE: includes/admin/class-llms-admin-media-protection-attachment-settings.php
  class LLMS_Admin_Media_Protection_Attachment_Settings (line 11) | class LLMS_Admin_Media_Protection_Attachment_Settings {
    method __construct (line 13) | public function __construct() {
    method attachment_fields_to_edit (line 27) | public function attachment_fields_to_edit( $form_fields, $post ) {
    method attachment_fields_to_save (line 70) | public function attachment_fields_to_save( $post, $attachment ) {
    method move_attachment_to_protected_dir (line 89) | function move_attachment_to_protected_dir( $attachment_id ) {

FILE: includes/admin/class-llms-admin-permalinks.php
  class LLMS_Admin_Permalinks (line 16) | class LLMS_Admin_Permalinks {
    method __construct (line 32) | public function __construct() {
    method load_on_permalinks_screen (line 43) | public function load_on_permalinks_screen() {
    method settings_init (line 55) | public function settings_init() {
    method settings (line 61) | 
Copy disabled (too large) Download .json
Condensed preview — 1659 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,871K chars).
[
  {
    "path": ".codeclimate.yml",
    "chars": 651,
    "preview": "vesion: '2'\n\nexclude_patterns:\n  # Ignore dot directories.\n  - .changelogs/\n  - .config/\n  - .github/\n  - .source/\n  - ."
  },
  {
    "path": ".cursor/BUGBOT.md",
    "chars": 97,
    "preview": "Do not review pull requests authored by dependabot[bot] or any automated dependency update bots.\n"
  },
  {
    "path": ".editorconfig",
    "chars": 976,
    "preview": "###\n#\n# This file is deployed into this repository via the \"Sync Organization Files\" workflow.\n#\n# Direct edits to this "
  },
  {
    "path": ".eslintrc.js",
    "chars": 198,
    "preview": "/**\n * ESlint config\n *\n * @package LifterLMS/Scripts/Dev\n *\n * @since Unknown\n * @version Unknown\n */\n\nconst config = r"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 85,
    "preview": "* @brianhogg\n\n# Full Site Editing.\nincludes/class-llms-block-templates.php @ideadude\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 6022,
    "preview": "Contributing to LifterLMS\n=========================\n\nWe welcome and encourage contributions from the community. If you'd"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_Report.md",
    "chars": 1171,
    "preview": "---\nname: Bug Report\nabout: Report a bug or issue\n\n---\n\n### Reproduction Steps\n\n+ Include clear and detailed step by ste"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Feature_Request.md",
    "chars": 479,
    "preview": "---\nname: Feature request\nabout: Suggest an idea or new feature for LifterLMS\n\n---\n\n**Is your feature request related to"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Question.md",
    "chars": 553,
    "preview": "---\nname: Question\nabout: Questions or 'how to' about LifterLMS\n\n---\n\nRemember that GitHub is NOT a support form! If you"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1674,
    "preview": "<!--\nContributors:\nPrior to opening a pull request, please review our contributing guidelines at https://github.com/goco"
  },
  {
    "path": ".github/SECURITY.md",
    "chars": 607,
    "preview": "Security Policy\n---------------\n\n## Supported Versions\n\nThe current minor version (currently LifterLMS 7.8.x) is the onl"
  },
  {
    "path": ".github/workflow-matrix.yml",
    "chars": 240,
    "preview": "###\n#\n# Custom workflow matrix configurations\n#\n# @link https://github.com/gocodebox/.github/tree/trunk/.github/actions/"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 1256,
    "preview": "name: \"CodeQL\"\n\non:\n  pull_request:\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n\n    strategy:\n      "
  },
  {
    "path": ".github/workflows/contributors.yml",
    "chars": 1090,
    "preview": "name: Contributors\n\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - trunk\n\nconcurrency:\n  group: ${{ github.workf"
  },
  {
    "path": ".github/workflows/keep-alive.yml",
    "chars": 1856,
    "preview": "###\n#\n# This workflow file is deployed into this repository via the \"Sync Organization Files\" workflow.\n#\n# Direct edits"
  },
  {
    "path": ".github/workflows/lint-js.yml",
    "chars": 1104,
    "preview": "###\n#\n# This workflow file is deployed into this repository via the \"Sync Organization Files\" workflow\n#\n# Direct edits "
  },
  {
    "path": ".github/workflows/ossar-analysis.yml",
    "chars": 567,
    "preview": "# This workflow integrates a collection of open source static analysis tools\n# with GitHub code scanning. For documentat"
  },
  {
    "path": ".github/workflows/project-automation.yml",
    "chars": 3191,
    "preview": "name: Issue & PR Automation\n\non:\n  issues:\n    types:\n      - opened\n      - reopened\n  pull_request_target:\n    types:\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 2429,
    "preview": "name: Release Publication and Distribution\n\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - trunk\n    paths:\n    "
  },
  {
    "path": ".github/workflows/sync-branches.yml",
    "chars": 1059,
    "preview": "###\n#\n# This workflow file is deployed into this repository via the \"Sync Organization Files\" workflow\n#\n# Direct edits "
  },
  {
    "path": ".github/workflows/test-e2e.yml",
    "chars": 2678,
    "preview": "###\n#\n# This workflow file is deployed into this repository via the \"Sync Organization Files\" workflow\n#\n# Direct edits "
  },
  {
    "path": ".github/workflows/test-js-unit.yml",
    "chars": 700,
    "preview": "name: Test JS Unit\n\non:\n  workflow_dispatch:\n  pull_request:\n    paths:\n        - src/js/**\n  # Once daily at 00:00 UTC."
  },
  {
    "path": ".github/workflows/test-phpunit.yml",
    "chars": 2804,
    "preview": "###\n#\n# This workflow file is deployed into this repository via the \"Sync Organization Files\" workflow\n#\n# Direct edits "
  },
  {
    "path": ".gitignore",
    "chars": 2472,
    "preview": "# Package managers.\nnode_modules/\n/vendor/\n\n# Lock file intentionally excluded to allow easier testing against multiple "
  },
  {
    "path": ".llmsconfig",
    "chars": 2120,
    "preview": "{\n\t\"build\": {\n\t\t\"custom\": [ \"js-additional\", \"js-builder\" ]\n\t},\n\t\"docs\": {\n\t\t\"package\": \"LifterLMS\"\n\t},\n\t\"pot\": {\n\t\t\"bug"
  },
  {
    "path": ".llmsdev.yml",
    "chars": 22,
    "preview": "pot:\n  dir: languages\n"
  },
  {
    "path": ".llmsdevrc",
    "chars": 997,
    "preview": "{\n\t\"readme\": {\n\t\t\"title\": \"LMS by LifterLMS - Online Course, Membership & Learning Management System Plugin for WordPres"
  },
  {
    "path": ".llmsenv.dist",
    "chars": 55,
    "preview": "WORDPRESS_PORT=8080\nWORDPRESS_TITLE=LifterLMS Core e2e\n"
  },
  {
    "path": ".source/README.md",
    "chars": 162,
    "preview": "LifterLMS Source Images\n=======================\n\nThis directory contains source images (.svg, .ai, .psd, etc...) for any"
  },
  {
    "path": ".wordpress-org/README.md",
    "chars": 2557,
    "preview": "WordPress.org Plugin Repository Content and Assets\n==================================================\n\nThis directory co"
  },
  {
    "path": ".wordpress-org/readme/01-header.md",
    "chars": 512,
    "preview": "=== LifterLMS - WP LMS for eLearning, Online Courses, & Quizzes ===\nContributors: lifterlms, chrisbadgett, strangerstudi"
  },
  {
    "path": ".wordpress-org/readme/05-description.md",
    "chars": 22273,
    "preview": "== Description ==\nLifterLMS is a secure easy-to-use WordPress LMS plugin packed with features to easily create & sell co"
  },
  {
    "path": ".wordpress-org/readme/10-installation.md",
    "chars": 1835,
    "preview": "== Installation ==\n\n#### Minimum System Requirements\n\nLifterLMS Requires\n\n+ PHP 7.4 or later\n+ WordPress 5.6 or later\n+ "
  },
  {
    "path": ".wordpress-org/readme/15-faqs.md",
    "chars": 5848,
    "preview": "== Frequently Asked Questions ==\n\n#### Where do I buy add-ons or bundles for my LifterLMS eLearning Website?\n\nYou can ex"
  },
  {
    "path": ".wordpress-org/readme/20-screenshots.md",
    "chars": 1117,
    "preview": "== Screenshots ==\n\n1. Infinitely customizable course catalog layouts: shown with course title, featured image, and instr"
  },
  {
    "path": ".wordpress-org/readme/25-changelog.md",
    "chars": 95,
    "preview": "== Changelog ==\n\n{{__CHANGELOG_ENTRIES__}}\n\n\n[Read the full changelog]({{__READ_MORE_LINK__}})\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 586939,
    "preview": "LifterLMS Changelog\n===================\n\nv10.0.0 - 2026-05-01\n--------------------\n\n##### New Features\n\n+ Lesson content"
  },
  {
    "path": "LICENSE",
    "chars": 35141,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 18113,
    "preview": "<h1 align=\"center\">\n  <img src=\".github/lifterlms-logo.png\" alt=\"LifterLMS logo\" width=\"300\">\n</h1>\n\n<p align=\"center\"><"
  },
  {
    "path": "assets/css/bricks-editor.css",
    "chars": 6084,
    "preview": "i.llms-bricks-icon:before {\n\tcontent: \"\";\n\tdisplay: block;\n\theight: 20px;\n\twidth: 20px;\n\tbackground-size: 20px 20px;\n\tba"
  },
  {
    "path": "assets/css/dancing-script.css",
    "chars": 1061,
    "preview": "/* vietnamese */\n@font-face {\n  font-family: 'Dancing Script';\n  src: url(\"../fonts/dancing-script/dancing-script-vietna"
  },
  {
    "path": "assets/css/imperial-script.css",
    "chars": 1068,
    "preview": "/* vietnamese */\n@font-face {\n  font-family: 'Imperial Script';\n  font-style: normal;\n  font-weight: 400;\n  font-display"
  },
  {
    "path": "assets/css/pirata-one.css",
    "chars": 695,
    "preview": "/* latin-ext */\n@font-face {\n  font-family: 'Pirata One';\n  src: url(\"../fonts/pirata-one/pirata-one-latin-ext.woff2\") f"
  },
  {
    "path": "assets/css/unifraktur-maguntia.css",
    "chars": 400,
    "preview": "/* latin */\n@font-face {\n  font-family: 'UnifrakturMaguntia';\n  src: url(\"../fonts/unifraktur-maguntia/unifraktur-magunt"
  },
  {
    "path": "assets/js/app/llms-achievements.js",
    "chars": 2555,
    "preview": "/**\n * Front End Achievements\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.14.0\n * @version 6.10.2\n */\n\nLLMS.Achievem"
  },
  {
    "path": "assets/js/app/llms-ajax.js",
    "chars": 2347,
    "preview": "/**\n * Main Ajax class\n * Handles Primary Ajax connection\n *\n * @package LifterLMS/Scripts\n *\n * @since Unknown\n * @vers"
  },
  {
    "path": "assets/js/app/llms-donut.js",
    "chars": 2277,
    "preview": "/**\n * Create a Donut Chart\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.9.0\n * @version 4.15.0\n *\n * @link https://g"
  },
  {
    "path": "assets/js/app/llms-forms.js",
    "chars": 9032,
    "preview": "/**\n * Forms\n *\n * @package LifterLMS/Scripts\n *\n * @since 5.0.0\n * @version 7.0.0\n */\n\nLLMS.Forms = {\n\n\t/**\n\t * Stores "
  },
  {
    "path": "assets/js/app/llms-instructors.js",
    "chars": 554,
    "preview": "/**\n * Instructors List\n *\n * @package LifterLMS/Scripts\n *\n * @since  Unknown\n * @version  Unknown\n */\n\nLLMS.Instructor"
  },
  {
    "path": "assets/js/app/llms-l10n.js",
    "chars": 1318,
    "preview": "/**\n * Localization functions for LifterLMS Javascript\n *\n * @package LifterLMS/Scripts\n *\n * @since  2.7.3\n * @version "
  },
  {
    "path": "assets/js/app/llms-lesson-preview.js",
    "chars": 1918,
    "preview": "/**\n * Handle Lesson Preview Elements\n *\n * @package LifterLMS/Scripts\n *\n * @since    3.0.0\n * @version  3.16.12\n */\n\nL"
  },
  {
    "path": "assets/js/app/llms-outline-collapse.js",
    "chars": 2692,
    "preview": "/**\n * Handle the Collapsible Syllabus Widget / Shortcode\n *\n * @package LifterLMS/Scripts\n *\n * @since Unknown\n * @vers"
  },
  {
    "path": "assets/js/app/llms-password-strength.js",
    "chars": 9525,
    "preview": "/**\n * Handle Password Strength Meter for registration and password update fields\n *\n * @package LifterLMS/Scripts\n *\n *"
  },
  {
    "path": "assets/js/app/llms-pricing-tables.js",
    "chars": 1436,
    "preview": "/**\n * Pricing Table UI\n *\n * @package LifterLMS/Scripts\n *\n * @since  Unknown.\n * @version  Unknown.\n */\n\nLLMS.Pricing_"
  },
  {
    "path": "assets/js/app/llms-quiz-attempt.js",
    "chars": 609,
    "preview": "/**\n * Quiz Attempt\n *\n * @package LifterLMS/Scripts\n *\n * @since 7.3.0\n * @version 7.3.0\n */\n\nLLMS.Quiz_Attempt = {\n\t/*"
  },
  {
    "path": "assets/js/app/llms-review.js",
    "chars": 2045,
    "preview": "/**\n * LifterLMS Reviews JS\n *\n * @package LifterLMS/Scripts\n *\n * @since Unknown\n * @version Unknown\n */\n\nLLMS.Review ="
  },
  {
    "path": "assets/js/app/llms-storage.js",
    "chars": 1768,
    "preview": "/* global LLMS, $ */\n\n// = include ../vendor/js.cookie.js\n\n/**\n * Create a no conflict reference to JS Cookies.\n *\n * @t"
  },
  {
    "path": "assets/js/app/llms-student-dashboard.js",
    "chars": 2096,
    "preview": "/**\n * Student Dashboard related JS\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.7.0\n * @since 3.10.0 Bind events on "
  },
  {
    "path": "assets/js/app/llms-tracking.js",
    "chars": 5417,
    "preview": "/* global LLMS, $ */\n\n/**\n * User event/interaction tracking.\n *\n * @since 3.36.0\n * @since 3.36.2 Fix JS error when set"
  },
  {
    "path": "assets/js/app/llms-visibility-toggle.js",
    "chars": 1927,
    "preview": "/**\n * Handle Password Visibility Toggle for LifterLMS Forms\n *\n * @package LifterLMS/Scripts\n *\n * @since TBD\n */\n\nLLMS"
  },
  {
    "path": "assets/js/app/rest.js",
    "chars": 1233,
    "preview": "/**\n * Rest Methods\n * Manages URL and Rest object parsing\n *\n * @package LifterLMS/Scripts\n *\n * @since Unknown\n * @ver"
  },
  {
    "path": "assets/js/builder/Collections/Lessons.js",
    "chars": 1912,
    "preview": "/**\n * Lessons Collection\n *\n * @since    3.13.0\n * @version  3.17.0\n */\ndefine( [ 'Models/Lesson' ], function( model ) "
  },
  {
    "path": "assets/js/builder/Collections/QuestionChoices.js",
    "chars": 2826,
    "preview": "/**\n * Question Choice Collection\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Models/QuestionChoice' ], fu"
  },
  {
    "path": "assets/js/builder/Collections/QuestionTypes.js",
    "chars": 728,
    "preview": "/**\n * Quiz Question Type Collection\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Models/QuestionType' ], f"
  },
  {
    "path": "assets/js/builder/Collections/Questions.js",
    "chars": 1442,
    "preview": "/**\n * Questions Collection\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Models/Question' ], function( mode"
  },
  {
    "path": "assets/js/builder/Collections/Sections.js",
    "chars": 997,
    "preview": "/**\n * Sections Collection\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Models/Section' ], function( model "
  },
  {
    "path": "assets/js/builder/Collections/loader.js",
    "chars": 476,
    "preview": "/**\n * Lessons Collection\n *\n * @since    3.13.0\n * @version  3.16.0\n */\ndefine( [\n\t\t'Collections/Lessons',\n\t\t'Collectio"
  },
  {
    "path": "assets/js/builder/Controllers/Construct.js",
    "chars": 3495,
    "preview": "/**\n * Constructor functions for constructing models, views, and collections\n *\n * @since    3.16.0\n * @version  3.17.1\n"
  },
  {
    "path": "assets/js/builder/Controllers/Debug.js",
    "chars": 1302,
    "preview": "/**\n * LifterLMS Builder Debugging suite\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\tretur"
  },
  {
    "path": "assets/js/builder/Controllers/Schemas.js",
    "chars": 1291,
    "preview": "/**\n * Model schema functions\n *\n * @since    3.17.0\n * @version  3.17.0\n */\ndefine( [], function() {\n\n\t/**\n\t * Main Sch"
  },
  {
    "path": "assets/js/builder/Controllers/Sync.js",
    "chars": 21231,
    "preview": "/**\n * Sync builder data to the server\n *\n * @since 3.16.0\n * @version 4.17.0\n */\ndefine( [], function() {\n\n\treturn func"
  },
  {
    "path": "assets/js/builder/Models/Abstract.js",
    "chars": 260,
    "preview": "/**\n * Abstract LifterLMS Model\n *\n * @since    3.17.0\n * @version  3.17.0\n */\ndefine( [ 'Models/_Relationships', 'Model"
  },
  {
    "path": "assets/js/builder/Models/Course.js",
    "chars": 5115,
    "preview": "/**\n * Course Model.\n *\n * @since 3.16.0\n * @since 3.24.0 Added `get_total_points()` method.\n * @since 3.37.11 Use lesso"
  },
  {
    "path": "assets/js/builder/Models/Image.js",
    "chars": 332,
    "preview": "/**\n * Image object model for use in various models for the 'image' attribute\n *\n * @since    3.16.0\n * @version  3.16.0"
  },
  {
    "path": "assets/js/builder/Models/Lesson.js",
    "chars": 11363,
    "preview": "/**\n * Lesson Model\n *\n * @since 3.13.0\n * @version 4.20.0\n */\ndefine( [ 'Models/Quiz', 'Models/_Relationships', 'Models"
  },
  {
    "path": "assets/js/builder/Models/Question.js",
    "chars": 8641,
    "preview": "/**\n * Quiz Question\n *\n * @since    3.16.0\n * @version  3.27.0\n */\ndefine( [\n\t\t'Models/Image',\n\t\t'Collections/Questions"
  },
  {
    "path": "assets/js/builder/Models/QuestionChoice.js",
    "chars": 1996,
    "preview": "/**\n * Quiz Question Choice\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Models/Image', 'Models/_Relationsh"
  },
  {
    "path": "assets/js/builder/Models/QuestionType.js",
    "chars": 2786,
    "preview": "/**\n * Quiz Question Type\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\treturn Backbone.Mode"
  },
  {
    "path": "assets/js/builder/Models/Quiz.js",
    "chars": 4791,
    "preview": "/**\n * Quiz Model.\n *\n * @since 3.16.0\n * @version 7.5.0\n */\ndefine( [\n\t\t'Collections/Questions',\n\t\t'Models/Lesson',\n\t\t'"
  },
  {
    "path": "assets/js/builder/Models/Section.js",
    "chars": 4690,
    "preview": "/**\n * Section Model\n *\n * @since 3.16.0\n * @version 4.20.0\n */\ndefine( [ 'Collections/Lessons', 'Models/_Relationships'"
  },
  {
    "path": "assets/js/builder/Models/_Relationships.js",
    "chars": 3649,
    "preview": "/**\n * Model relationships mixin\n *\n * @since    3.16.0\n * @version  3.16.11\n */\ndefine( [], function() {\n\n\treturn {\n\n\t\t"
  },
  {
    "path": "assets/js/builder/Models/_Utilities.js",
    "chars": 3659,
    "preview": "/**\n * Utility functions for Models.\n *\n * @since 3.16.0\n * @version 7.4.0\n */\ndefine( [], function() {\n\n\treturn {\n\n\t\tfi"
  },
  {
    "path": "assets/js/builder/Models/loader.js",
    "chars": 634,
    "preview": "/**\n * Load all models\n *\n * @return   obj\n * @since    3.16.0\n * @version  3.17.0\n */\ndefine( [\n\t\t'Models/Abstract',\n\t\t"
  },
  {
    "path": "assets/js/builder/Schemas/Lesson.js",
    "chars": 7647,
    "preview": "/**\n * Lesson Schemas\n *\n * @since    3.17.0\n * @version  3.25.4\n */\ndefine( [], function() {\n\n\treturn window.llms.hooks"
  },
  {
    "path": "assets/js/builder/Schemas/Quiz.js",
    "chars": 3601,
    "preview": "/**\n * Quiz Schema.\n *\n * @since 3.17.6\n * @since 7.4.0 Added upsell for Question Bank and condition in `random_question"
  },
  {
    "path": "assets/js/builder/Views/Assignment.js",
    "chars": 9251,
    "preview": "/**\n * Single Assignment View.\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.17.0\n * @version 5.4.0\n */\n\ndefine( [\n\t\t'"
  },
  {
    "path": "assets/js/builder/Views/Course.js",
    "chars": 4537,
    "preview": "/**\n * Single Course View\n *\n * @since    3.13.0\n * @version  3.16.0\n */\ndefine( [\n\t'Views/SectionList',\n\t'Views/_Detach"
  },
  {
    "path": "assets/js/builder/Views/Editor.js",
    "chars": 3267,
    "preview": "/**\n * Sidebar Editor View\n *\n * @since    3.16.0\n * @version  3.27.0\n */\ndefine( [\n\t\t'Views/LessonEditor',\n\t\t'Views/Qui"
  },
  {
    "path": "assets/js/builder/Views/Elements.js",
    "chars": 4606,
    "preview": "/**\n * Sidebar Elements View\n *\n * @since    3.16.0\n * @version  3.16.12\n */\ndefine( [ 'Models/Section', 'Views/Section'"
  },
  {
    "path": "assets/js/builder/Views/FormattingToolbar.js",
    "chars": 2481,
    "preview": "/**\n * Sidebar Elements View\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\treturn Backbone.V"
  },
  {
    "path": "assets/js/builder/Views/Lesson.js",
    "chars": 5886,
    "preview": "/**\n * Single Lesson View\n * @since    3.16.0\n * @version  3.27.0\n */\ndefine( [\n\t\t'Views/_Detachable',\n\t\t'Views/_Editabl"
  },
  {
    "path": "assets/js/builder/Views/LessonEditor.js",
    "chars": 3180,
    "preview": "/**\n * Lesson Editor (Sidebar) View\n *\n * @package LifterLMS/Scripts/Builder\n *\n * @since 3.17.0\n * @since 3.35.2 Added "
  },
  {
    "path": "assets/js/builder/Views/LessonList.js",
    "chars": 1902,
    "preview": "/**\n * Single Section View\n *\n * @since    3.13.0\n * @version  3.16.0\n */\ndefine( [ 'Views/Lesson', 'Views/_Receivable' "
  },
  {
    "path": "assets/js/builder/Views/Popover.js",
    "chars": 1980,
    "preview": "/**\n * Popover View\n *\n * @since 3.16.0\n * @version 4.0.0\n */\ndefine( [], function() {\n\n\treturn Backbone.View.extend( {\n"
  },
  {
    "path": "assets/js/builder/Views/PostSearch.js",
    "chars": 3362,
    "preview": "/**\n * Post Popover Search content View\n *\n * @since 3.16.0\n * @version 4.4.0\n */\ndefine( [], function() {\n\n\treturn Back"
  },
  {
    "path": "assets/js/builder/Views/Question.js",
    "chars": 7364,
    "preview": "/**\n * Single Question View.\n *\n * @since 3.16.0\n * @version 7.8.0\n */\ndefine( [\n\t\t'Views/_Detachable',\n\t\t'Views/_Editab"
  },
  {
    "path": "assets/js/builder/Views/QuestionBank.js",
    "chars": 571,
    "preview": "/**\n * Quiz question bank view\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Views/QuestionType' ], function"
  },
  {
    "path": "assets/js/builder/Views/QuestionChoice.js",
    "chars": 2810,
    "preview": "/**\n * Single Question Choice View\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Views/_Editable', ], function("
  },
  {
    "path": "assets/js/builder/Views/QuestionChoiceList.js",
    "chars": 973,
    "preview": "/**\n * Quiz question bank view\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Views/QuestionChoice' ], functi"
  },
  {
    "path": "assets/js/builder/Views/QuestionList.js",
    "chars": 4350,
    "preview": "/**\n * Quiz question bank view\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [ 'Views/Question' ], function( Quest"
  },
  {
    "path": "assets/js/builder/Views/QuestionType.js",
    "chars": 4140,
    "preview": "/**\n * Question Type View\n *\n * @since 3.16.0\n * @since 3.30.1 Fixed issue causing multiple binds for add_existing_quest"
  },
  {
    "path": "assets/js/builder/Views/Quiz.js",
    "chars": 10370,
    "preview": "/**\n * Single Quiz View.\n *\n * @since 3.16.0\n * @version 5.4.0\n */\ndefine( [\n\t\t'Models/Quiz',\n\t\t'Views/Popover',\n\t\t'View"
  },
  {
    "path": "assets/js/builder/Views/Section.js",
    "chars": 5942,
    "preview": "/**\n * Single Section View\n * @since    3.13.0\n * @version  3.16.12\n */\ndefine( [\n\t\t'Views/LessonList',\n\t\t'Views/_Editab"
  },
  {
    "path": "assets/js/builder/Views/SectionList.js",
    "chars": 1294,
    "preview": "/**\n * Single Section View\n *\n * @since    3.13.0\n * @version  3.16.0\n */\ndefine( [ 'Views/Section', 'Views/_Receivable'"
  },
  {
    "path": "assets/js/builder/Views/SettingsFields.js",
    "chars": 10768,
    "preview": "/**\n * Model settings fields view\n *\n * @since 3.17.0\n * @version 4.7.0\n */\ndefine( [], function() {\n\n\treturn Backbone.V"
  },
  {
    "path": "assets/js/builder/Views/Sidebar.js",
    "chars": 6373,
    "preview": "/**\n * Main sidebar view\n *\n * @since 3.16.0\n * @version 7.2.0\n */\ndefine( [\n\t'Views/Editor',\n\t'Views/Elements',\n\t'Views"
  },
  {
    "path": "assets/js/builder/Views/Utilities.js",
    "chars": 1419,
    "preview": "/**\n * Sidebar Utilities View\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\treturn Backbone."
  },
  {
    "path": "assets/js/builder/Views/_Detachable.js",
    "chars": 1169,
    "preview": "/**\n * Detachable model\n *\n * @package LifterLMS/Scripts\n *\n * @since    3.16.12\n * @version  3.16.12\n */\n\ndefine( [], f"
  },
  {
    "path": "assets/js/builder/Views/_Editable.js",
    "chars": 15615,
    "preview": "/**\n * Handles UX and Events for inline editing of views\n *\n * Use with a Model's View\n * Allows editing model.title fie"
  },
  {
    "path": "assets/js/builder/Views/_Receivable.js",
    "chars": 1516,
    "preview": "/**\n * _receive override for Backbone.CollectionView core\n * enables connection with jQuery UI draggable buttons\n *\n * @"
  },
  {
    "path": "assets/js/builder/Views/_Shiftable.js",
    "chars": 1738,
    "preview": "/**\n * Shiftable view mixin function\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\treturn {\n"
  },
  {
    "path": "assets/js/builder/Views/_Subview.js",
    "chars": 3437,
    "preview": "/**\n * Subview utility mixin\n *\n * @since    3.16.0\n * @version  3.16.0\n */\ndefine( [], function() {\n\n\treturn {\n\n\t\tsubsc"
  },
  {
    "path": "assets/js/builder/Views/_Trashable.js",
    "chars": 1342,
    "preview": "/**\n * Trashable model\n *\n * @type     {Object}\n * @since    3.16.12\n * @version  3.16.12\n */\ndefine( [], function() {\n\n"
  },
  {
    "path": "assets/js/builder/Views/_loader.js",
    "chars": 512,
    "preview": "/**\n * Load view mixins\n *\n * @package LifterLMS/Scripts\n *\n * @since    3.17.1\n * @version  3.17.1\n */\n\ndefine( [\n\t\t'Vi"
  },
  {
    "path": "assets/js/builder/backbone.js",
    "chars": 214,
    "preview": "/**\n * Returns the WordPress-loaded version of Backbone for use with things that need it and use Require.\n *\n * @return "
  },
  {
    "path": "assets/js/builder/jquery.js",
    "chars": 231,
    "preview": "/**\n * Returns the WordPress-loaded version of Underscore for use with things that need it and use Require.\n *\n * @packa"
  },
  {
    "path": "assets/js/builder/main.js",
    "chars": 9120,
    "preview": "/**\n * LifterLMS JS Builder App Bootstrap\n *\n * @since 3.16.0\n * @since 3.37.11 Added `_.getEditor()` helper.\n * @versio"
  },
  {
    "path": "assets/js/builder/underscore.js",
    "chars": 209,
    "preview": "/**\n * Returns the WordPress-loaded version of Underscore for use with things that need it and use Require.\n *\n * @retur"
  },
  {
    "path": "assets/js/builder/vendor/almond.js",
    "chars": 11993,
    "preview": "/**\n * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.\n * Released under MIT license, http://g"
  },
  {
    "path": "assets/js/builder/vendor/backbone.collectionView.js",
    "chars": 49220,
    "preview": "/*!\n* Backbone.CollectionView, v1.3.4\n* Copyright (c)2013 Rotunda Software, LLC.\n* Distributed under MIT license\n* http:"
  },
  {
    "path": "assets/js/builder/vendor/backbone.trackit.js",
    "chars": 6473,
    "preview": "/**\n * backbone.trackit - 0.1.0\n *\n * The MIT License\n * Copyright (c) 2013 The New York Times, CMS Group, Matthew DeLam"
  },
  {
    "path": "assets/js/builder/vendor/wp-hooks.js",
    "chars": 4901,
    "preview": "/**\n * This is a slightly modified and forward compatible version of the @wordpress/hooks package\n * as included in the "
  },
  {
    "path": "assets/js/llms-admin-forms.js",
    "chars": 3294,
    "preview": "/**\n * Show an upgrade to custom fields notice when viewing the forms post type table\n *\n * @since 5.0.0\n * @version 5.0"
  },
  {
    "path": "assets/js/llms-admin-media-protection-attachment-settings.js",
    "chars": 1491,
    "preview": "( function() {\n\tif ( 'undefined' === typeof wp || 'undefined' === typeof wp.media || 'undefined' === typeof wp.media.vie"
  },
  {
    "path": "assets/js/llms-admin-settings.js",
    "chars": 4436,
    "preview": ";/**\n * LifterLMS Settings Pages UI / UX\n *\n * @since    3.7.3\n * @version  3.18.0\n */( function( $, undefined ) {\n\n\twin"
  },
  {
    "path": "assets/js/llms-admin-tables.js",
    "chars": 8857,
    "preview": "/**\n * LifterLMS Admin Tables\n * @since    3.2.0\n * @version  3.28.1\n */\n;( function( $, undefined ) {\n\n\twindow.llms = w"
  },
  {
    "path": "assets/js/llms-admin-wizard.js",
    "chars": 2728,
    "preview": "/**\n * JS from the admin setup wizard\n *\n * @since 4.8.0\n * @version 4.8.0\n */\n\n( function() {\n\tconst\n\t\tcurrStep       ="
  },
  {
    "path": "assets/js/llms-admin.js",
    "chars": 9427,
    "preview": "/**\n * LifterLMS Admin Panel Javascript\n *\n * @since Unknown\n * @version 7.3.0\n *\n * @param obj $ Traditional jQuery ref"
  },
  {
    "path": "assets/js/llms-ajax.js",
    "chars": 481,
    "preview": "function Ajax ( type, data, cache ) {\n\n\tthis.type     = type;\n\tthis.data     = data;\n\tthis.cache    = cache;\n\tthis.dataT"
  },
  {
    "path": "assets/js/llms-analytics.js",
    "chars": 12029,
    "preview": ";/**\n * LifterLMS Admin Reporting Widgets & Charts\n *\n * @since 3.0.0\n * @since 3.17.2 Unknown.\n * @since 3.33.1 Fix iss"
  },
  {
    "path": "assets/js/llms-favorites.js",
    "chars": 2425,
    "preview": "/* global LLMS, $ */\n/* jshint strict: true */\n\n/**\n * Front End Favorite Class.\n *\n * @type {Object}\n *\n * @since 7.5.0"
  },
  {
    "path": "assets/js/llms-focus-mode.js",
    "chars": 790,
    "preview": "/**\n * LifterLMS Focus Mode sidebar toggle.\n *\n * @package LifterLMS\n *\n * @since 10.0.0\n * @version 10.0.0\n */\n( functi"
  },
  {
    "path": "assets/js/llms-form-checkout.js",
    "chars": 12791,
    "preview": "/**\n * LifterLMS Checkout Screen related events and interactions\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.0.0\n * "
  },
  {
    "path": "assets/js/llms-launch-course-button.js",
    "chars": 481,
    "preview": "/**\n * Add Launch Course Builder button to the classic editor.\n *\n * @since Unknown\n * @version 3.35.0\n */\n\n( function( "
  },
  {
    "path": "assets/js/llms-metabox-achievement.js",
    "chars": 1874,
    "preview": "( function( $ ) {\n\n\t// Open Media Manager modal.\n\t$( '.achievement_image_button' ).click( function( e ) {\n\n\t\t// Create M"
  },
  {
    "path": "assets/js/llms-metabox-certificate.js",
    "chars": 1934,
    "preview": "jQuery( document ).ready(function($){\n\n\t$( '.certificate_image_button' ).click(function(e) {\n\n\t\t// Create Media Manager "
  },
  {
    "path": "assets/js/llms-metabox-fields.js",
    "chars": 521,
    "preview": "/**\n * Global admin functions.\n *\n * @since Unknown\n * @version 3.35.0\n */\n\n( function( $ ){\n\n\t// Toggle sales price set"
  },
  {
    "path": "assets/js/llms-metabox-instructors.js",
    "chars": 1316,
    "preview": "/**\n * Instructors Metabox\n *\n * @since    3.13.0\n * @version  3.13.0\n */\n( function( $ ) {\n\n\twindow.llms = window.llms "
  },
  {
    "path": "assets/js/llms-metabox-options.js",
    "chars": 961,
    "preview": "/**\n * JS for the Course and Membership metabox options\n *\n * @since 8.0.0\n */\n\n( function( $ ){\n\n\t$( '.llms-mb-containe"
  },
  {
    "path": "assets/js/llms-metabox-product.js",
    "chars": 29460,
    "preview": "/**\n * Product Options MetaBox.\n *\n * Displays on Course & Membership Post Types.\n *\n * @since 3.0.0\n * @since 3.30.3 Un"
  },
  {
    "path": "assets/js/llms-metabox-students.js",
    "chars": 4219,
    "preview": "/**\n * LifterLMS Students Metabox Functions\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.0.0\n * @version 3.33.0\n */\n\n"
  },
  {
    "path": "assets/js/llms-metabox-voucher.js",
    "chars": 4816,
    "preview": "( function( $ ) {\n\n\tvar deleteIds = [];\n\n\t$( document ).ready( function () {\n\n\t\tvar changeNotSaved          = false;\n\t\tv"
  },
  {
    "path": "assets/js/llms-notifications.js",
    "chars": 5349,
    "preview": ";/**\n * LifterLMS Basic Notifications Displayer\n *\n * @since    3.8.0\n * @version  3.22.0\n */( function( $ ) {\n\n\tvar llm"
  },
  {
    "path": "assets/js/llms-quiz-attempt-review.js",
    "chars": 2666,
    "preview": ";/**\n * Quiz attempt review / grading UI & UX\n *\n * @since 3.16.0\n * @since 3.30.3 Unknown.\n * @version 5.3.0\n */( funct"
  },
  {
    "path": "assets/js/llms-quiz.js",
    "chars": 27448,
    "preview": ";/* global LLMS, $ */\n/* jshint strict: true */\n\n/**\n * Front End Quiz Class.\n *\n * @type {Object}\n *\n * @since 1.0.0\n *"
  },
  {
    "path": "assets/js/llms-view-manager.js",
    "chars": 1885,
    "preview": "/**\n * JS events for the view manager\n *\n * @package LifterLMS/Scripts\n *\n * @since 3.8.0\n * @since 4.2.0 Added access p"
  },
  {
    "path": "assets/js/llms-widget-syllabus.js",
    "chars": 1734,
    "preview": "( function( $ ) {\n\n\twindow.llms = window.llms || {};\n\n\t/**\n\t * Manage\n\t *\n\t * @return obj    instance of the class\n\t * @"
  },
  {
    "path": "assets/js/partials/_metabox-field-repeater.js",
    "chars": 11845,
    "preview": "/**\n * LifterLMS Admin Metabox Repeater Field\n *\n * @package LifterLMS/Scripts/Partials\n *\n * @since 3.11.0\n * @version "
  },
  {
    "path": "assets/js/private/llms-metaboxes.js",
    "chars": 27850,
    "preview": "/**\n * LifterLMS Admin Panel Metabox Functions\n *\n * @since 3.0.0\n * @version 7.1.1\n */\n ( function( $ ) {\n\n\t $( documen"
  },
  {
    "path": "assets/js/private/llms.js",
    "chars": 3253,
    "preview": "/**\n * Main LLMS Namespace\n *\n * @since 1.0.0\n * @version 5.3.3\n */\n\nvar LLMS = window.LLMS || {};\n( function( $ ){\n\n\t'u"
  },
  {
    "path": "assets/js/vendor/jquery.matchHeight.js",
    "chars": 9255,
    "preview": "/**\n* jquery-match-height 0.7.0 by @liabru\n* http://brm.io/jquery-match-height/\n* License: MIT\n*/\n\n;(function(factory) {"
  },
  {
    "path": "assets/js/vendor/js.cookie.js",
    "chars": 3882,
    "preview": "/*!\n * JavaScript Cookie v2.2.1\n * https://github.com/js-cookie/js-cookie\n *\n * Copyright 2006, 2015 Klaus Hartl & Fagne"
  },
  {
    "path": "assets/scss/_includes/_buttons.scss",
    "chars": 2936,
    "preview": ".llms-button-action,\n.llms-button-danger,\n.llms-button-primary,\n.llms-button-secondary {\n\tborder:none;\n\tborder-radius: 8"
  },
  {
    "path": "assets/scss/_includes/_extends.scss",
    "chars": 395,
    "preview": "%cf,\n%clearfix {\n\t&:before,\n\t&:after {\n\t    content: \" \";\n\t    display: table;\n\t}\n\n\t&:after {\n    \tclear: both;\n\t}\n}\n\n\n\n"
  },
  {
    "path": "assets/scss/_includes/_grid.scss",
    "chars": 701,
    "preview": "//\n// Floated columns.\n//\n// Utilized prior to the introduction of `.llms-flex-cols`. Prefer\n// usage of flex cols for n"
  },
  {
    "path": "assets/scss/_includes/_llms-donut.scss",
    "chars": 1130,
    "preview": ".llms-donut {\n\n\t@include clearfix;\n\n\tbackground-color: #f1f1f1;\n\tbackground-image: none;\n\tborder-radius: 50%;\n\tcolor: $c"
  },
  {
    "path": "assets/scss/_includes/_llms-form-field.scss",
    "chars": 6018,
    "preview": ".llms-form-fields {\n\t@extend %clearfix;\n\tbox-sizing: border-box;\n\t& * {\n\t\tbox-sizing: border-box;\n\t}\n\t&.flush {\n\t\t.llms-"
  },
  {
    "path": "assets/scss/_includes/_mixins.scss",
    "chars": 2167,
    "preview": "\n@mixin clearfix() {\n\t&:before,\n\t&:after {\n\t    content: \" \";\n\t    display: table;\n\t}\n\t&:after {\n\t    clear: both;\n\t}\n}\n"
  },
  {
    "path": "assets/scss/_includes/_quiz-result-question-list.scss",
    "chars": 2391,
    "preview": ".llms-quiz-attempt-results {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style-type: none;\n\n\t.llms-quiz-attempt-question {\n\t\tbackgrou"
  },
  {
    "path": "assets/scss/_includes/_tooltip.scss",
    "chars": 1991,
    "preview": ".lifterlms, // Settings & Course Builder.\n.llms-metabox, // Some Metaboxes.\n.llms-mb-container, // Other Metaboxes.\n.llm"
  },
  {
    "path": "assets/scss/_includes/_vars-brand-colors.scss",
    "chars": 506,
    "preview": "//\n// LifterLMS Brand Colors\n// Currently overrides brand colors on the admin panel\n//\n\n$color-brand-blue: #466dd8;\n$col"
  },
  {
    "path": "assets/scss/_includes/_vars.scss",
    "chars": 1235,
    "preview": "// ----- LifterLMS Brand Colors ----- \\\\\n$color-brand-dark-blue: #243c56;\n\n$color-brand-blue: #466dd8;\n$color-brand-blue"
  },
  {
    "path": "assets/scss/_includes/vendor/_font-awesome.scss",
    "chars": 37414,
    "preview": "/*!\n *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/lice"
  },
  {
    "path": "assets/scss/admin/_course-builder.scss",
    "chars": 29554,
    "preview": "body.admin_page_llms-course-builder {\n\tbackground: #fff;\n\n\t#adminmenumain { display: none; }\n\t#wpbody-content { padding-"
  },
  {
    "path": "assets/scss/admin/_dashboard-widget.scss",
    "chars": 1369,
    "preview": "#llms_dashboard_widget {\n\n\t.inside {\n\t\tmargin: 0;\n\t\tpadding-bottom: 8px;\n\t}\n\n\t.llms-dashboard-widget-wrap {\n\t\tdisplay: f"
  },
  {
    "path": "assets/scss/admin/_dashboard.scss",
    "chars": 2190,
    "preview": ".wrap.llms-dashboard {\n\n\t.llms-inside-wrap {\n\t\tpadding-top: 30px;\n\t}\n\n\t#poststuff {\n\n\t\th2 {\n\t\t\tpadding: 12px 20px;\n\t\t}\n\n"
  },
  {
    "path": "assets/scss/admin/_fonts.scss",
    "chars": 132,
    "preview": "#llms-options-page-contents {\n\th2 {\n\t\tcolor: #999;\n\t\tfont-weight: 500;\n\t\tletter-spacing: 2px;\n\t\tborder-bottom: 1px solid"
  },
  {
    "path": "assets/scss/admin/_llms-table.scss",
    "chars": 3381,
    "preview": ".llms-table-wrap {\n\tposition: relative;\n}\n\n.llms-table-header {\n\tpadding: 0;\n\n\t@include clearfix();\n\n\th2 {\n\t\tfont-size: "
  },
  {
    "path": "assets/scss/admin/_main.scss",
    "chars": 6036,
    "preview": ".wrap.lifterlms {\n\tmargin-top: 0;\n}\n\n.llms-header {\n\tbackground-color: #FFF;\n\tmargin: 0 0 0 -20px;\n\tpadding: 20px 10px;\n"
  },
  {
    "path": "assets/scss/admin/_media-protection.scss",
    "chars": 131,
    "preview": ".llms-media-protection-warning {\n\tborder-left: 4px solid $color-orange;\n\tpadding-left: 10px;\n\tmax-width: 400px;\n\tmargin:"
  },
  {
    "path": "assets/scss/admin/_quiz-attempt-review.scss",
    "chars": 270,
    "preview": ".llms-remarks {\n\n\t.llms-remarks-field {\n\t\theight: 120px;\n\t\twidth: 100%;\n\t}\n\n\tinput[type=\"number\"] {\n\t\twidth: 60px;\n\t}\n\n\n"
  },
  {
    "path": "assets/scss/admin/_reporting.scss",
    "chars": 6733,
    "preview": ".llms-reporting.wrap {\n\n\t.llms-options-page-contents {\n\n\t\t.llms-nav-tab-wrapper.llms-nav-secondary {\n\t\t\tbox-shadow: 0 1p"
  },
  {
    "path": "assets/scss/admin/_resources.scss",
    "chars": 2083,
    "preview": ".wrap.llms-resources {\n\n\t.llms-inside-wrap {\n\t\tpadding-top: 30px;\n\t}\n\n\t#poststuff {\n\n\t\t#post-body.columns-2 {\n\t\t\tmargin-"
  },
  {
    "path": "assets/scss/admin/_settings.scss",
    "chars": 3075,
    "preview": ".wrap.llms-reporting,\n.wrap.lifterlms-settings,\n.wrap.llms-status {\n\n\t.llms-inside-wrap {\n\t\tbox-sizing: border-box;\n\t\tma"
  },
  {
    "path": "assets/scss/admin/_tabs.scss",
    "chars": 2613,
    "preview": ".llms-nav-tab-wrapper {\n\tbackground: $color-blue;\n\tmargin: 20px 0;\n\n\t&.llms-nav-secondary {\n\t\tbackground: #e1e1e1;\n\n\t\t.l"
  },
  {
    "path": "assets/scss/admin/_wp-menu.scss",
    "chars": 369,
    "preview": "#adminmenu {\n\n\t.toplevel_page_lifterlms .wp-menu-image img {\n\t\tpadding-top: 6px;\n\t\twidth: 20px;\n\t}\n\n\t.toplevel_page_lift"
  },
  {
    "path": "assets/scss/admin/breakpoints/_1030up.scss",
    "chars": 1193,
    "preview": "/******************************************************************\n\nDesktop Stylesheet\n\n*******************************"
  },
  {
    "path": "assets/scss/admin/breakpoints/_1240up.scss",
    "chars": 243,
    "preview": "/******************************************************************\n\nlarge Monitor Stylesheet\n\n*************************"
  },
  {
    "path": "assets/scss/admin/breakpoints/_481up.scss",
    "chars": 267,
    "preview": "/******************************************************************\n\nLarger Phones\n\n************************************"
  },
  {
    "path": "assets/scss/admin/breakpoints/_768up.scss",
    "chars": 1134,
    "preview": "/******************************************************************\n\nTablets and small computers\n\n**********************"
  },
  {
    "path": "assets/scss/admin/breakpoints/_base.scss",
    "chars": 1339,
    "preview": "/******************************************************************\n\nBase Mobile\n\n**************************************"
  },
  {
    "path": "assets/scss/admin/metaboxes/_builder-launcher.scss",
    "chars": 138,
    "preview": ".llms-builder-launcher {\n\n\tp {\n\t\tmargin-top: 0;\n\t}\n\n\tol {\n\t\tmargin-top: -6px;\n\t}\n\n\t.llms-button-primary {\n\t\tbox-sizing: "
  },
  {
    "path": "assets/scss/admin/metaboxes/_llms-metabox.scss",
    "chars": 3737,
    "preview": "\n// This is a \"legacy\" rule that may be removable\n.llms-mb-list {\n\n\tlabel {\n\t\tfont-size: 15px;\n\t\tfont-weight: 700;\n\t\tlin"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-engagements-type.scss",
    "chars": 925,
    "preview": ".submitbox .llms-mb-section,\n.llms-award-engagement-submitbox .llms-mb-list {\n\tmargin-bottom: 12px;\n\t&:last-of-type {\n\t\t"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-field-repeater.scss",
    "chars": 590,
    "preview": ".llms-mb-container .tab-content ul:not(.select2-selection__rendered).llms-mb-repeater-fields > li.llms-mb-list {\n\tborder"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-instructors.scss",
    "chars": 187,
    "preview": "._llms_instructors_data.repeater {\n\t.llms-repeater-rows .llms-repeater-row:first-child {\n\t\t.llms-repeater-remove { displ"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-orders.scss",
    "chars": 1082,
    "preview": ".post-type-llms_order #post-body-content { display: none; }\n#lifterlms-order-details {\n\t.handlediv,\n\t.handlediv.button-l"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-product.scss",
    "chars": 2837,
    "preview": ".llms-metabox {\n\n\t> p:first-child {\n\t\tmargin-top: 0;\n\t}\n\n\t#llms-new-access-plan-model {\n\t\tdisplay: none;\n\t}\n\n\t.llms-acce"
  },
  {
    "path": "assets/scss/admin/metaboxes/_metabox-students.scss",
    "chars": 192,
    "preview": ".llms-metabox-students {\n\t.llms-table {\n\t\ttr .name {\n\t\t\ttext-align: left;\n\t\t}\n\t}\n\n\t.llms-add-student:hover {\n\t\tcolor: $c"
  },
  {
    "path": "assets/scss/admin/modules/_forms.scss",
    "chars": 3393,
    "preview": "/******************************************************************\n\nForm Styles\n\n**************************************"
  },
  {
    "path": "assets/scss/admin/modules/_icons.scss",
    "chars": 1919,
    "preview": "/******************************************************************\n\nSVG Styles\n\n***************************************"
  },
  {
    "path": "assets/scss/admin/modules/_llms-order-note.scss",
    "chars": 518,
    "preview": ".llms-order-note {\n\n\t.llms-order-note-content {\n\t\tbackground: #efefef;\n\t\tmargin-bottom: 10px;\n\t\tpadding: 10px;\n\t\tpositio"
  },
  {
    "path": "assets/scss/admin/modules/_mb-tabs.scss",
    "chars": 1045,
    "preview": "/******************************************************************\n\nMetabox Tabs\n\n*************************************"
  },
  {
    "path": "assets/scss/admin/modules/_merge-codes.scss",
    "chars": 813,
    "preview": ".button.llms-merge-code-button {\n\tvertical-align: middle;\n\tsvg {\n\t\tmargin-right: 2px;\n\t\tposition: relative;\n\t\ttop: 4px;\n"
  },
  {
    "path": "assets/scss/admin/modules/_top-modal.scss",
    "chars": 4224,
    "preview": "/******************************************************************\n\nStyles for topModal modal\n\n************************"
  },
  {
    "path": "assets/scss/admin/modules/_voucher.scss",
    "chars": 1760,
    "preview": "a.llms-voucher-delete {\n\tbackground: $color-danger;\n\tcolor: $color-white;\n\tdisplay: block;\n\tpadding: 4px 2px;\n\ttext-deco"
  },
  {
    "path": "assets/scss/admin/modules/_widgets.scss",
    "chars": 2492,
    "preview": ".llms-widget {\n\tbackground-color: #FFF;\n\tborder: 1px solid #dedede;\n\tborder-radius: 12px;\n\tbox-shadow: 0px 0px 1px rgba("
  },
  {
    "path": "assets/scss/admin/partials/_grid.scss",
    "chars": 3570,
    "preview": "/******************************************************************\n\nGrids for Breakpoints\n\n****************************"
  },
  {
    "path": "assets/scss/admin/post-tables/_llms_orders.scss",
    "chars": 128,
    "preview": ".wp-list-table {\n\t@include order_status_badges();\n}\n\n#lifterlms-order-transactions .llms-table tfoot th {\n\ttext-align: r"
  },
  {
    "path": "assets/scss/admin/post-tables/_post-tables.scss",
    "chars": 110,
    "preview": ".llms-post-table-post-filter {\n\tdisplay: inline-block;\n\tmargin-right: 6px;\n\tmax-width: 100%;\n\twidth: 220px;\n}\n"
  }
]

// ... and 1459 more files (download for full content)

About this extraction

This page contains the full source code of the gocodebox/lifterlms GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1659 files (9.4 MB), approximately 2.6M tokens, and a symbol index with 7986 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!